【问题标题】:How to develop an Import/Export Functionality for my node application如何为我的节点应用程序开发导入/导出功能
【发布时间】:2020-01-28 12:06:00
【问题描述】:

我在 Nodejs 中有一个配置应用程序。它有一个Componentnameuuid。一个Component 可以有多个Schemas。一个Schema 有一个uuidnamecomponentIdjson。一个Schema 可以有多个ConfigurationsConfigurationnameschemaIdjsonuuidSchema 可以包含许多其他 Schemas 的引用。现在我想创建一个从应用程序的一个实例导出所有数据并将其导入另一个实例的功能。最简单的方法应该是什么?有几个问题

  1. 如何告诉应用程序要导出什么。现在我认为组件、模式和配置应该有单独的数组。喜欢
{
    components: ['id1', 'id2'],
    schemas: ['s1', 's2'],
    configuration: ['c1', 'c2'],
}

此数据应发送到应用程序以返回包含所有信息的文件,该文件稍后将用于在另一个实例中导入

  1. 真正的问题是我的导出文件应该是什么样子,记住还涉及依赖关系,并且依赖关系也可能重叠。例如,一个模式可以在其 json 字段中引用许多其他模式。例如schema1 具有schema2schema4 作为其依赖项。所以还有另一个架构schema5 也需要schema2。所以在导入时,我们必须确保在保存schema1schema5 之前先保存schema2。如何表示需要顺序以及重叠依赖项的此类文件,确保在导入时不会两次保存schema2。下面以schema1json 为例
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "p1": {
        "$ref": "link-to-schema2"
    },
    "p2": {
        "$ref": "link-to-schema4"
    },

}

  1. 导入时我应该遵循的逐步 sudo 算法应该是什么。

【问题讨论】:

    标签: node.js algorithm import architecture export


    【解决方案1】:

    这是topological sort 的完美机会。

    除去组件、模式和配置术语,您拥有的是(各种)对象,它们首先依赖于其他存在的对象。拓扑排序将创建一个仅具有前向依赖关系的顺序(假设您没有循环依赖关系,在这种情况下是不可能的)。

    但复杂之处在于您拥有多种方向的依赖信息。必须在其架构之前创建组件。必须在它所依赖的模式之后创建模式。这些模式也可能属于必须创建的其他组件,这并非不可能。

    第一步是编写一个函数,该函数接受一个对象并返回一组可从对象本身发现的依赖关系。所以我们希望dependencyRelations(object1 提供类似[[object1, object2], [object3, object1], [object1, object4]] 的内容。其中object1 取决于object2 存在。 (注意,object1 将在每一对中,但可以是第一或第二。)

    如果每个对象都有一个名为 uniqueName 的方法来唯一标识它,那么我们可以编写一个类似这样的方法(抱歉,所有代码都是在这里输入的,没有经过测试,可能存在语法错误,但想法是正确的):

    function dependencyInfo (startingObject) {
        const nameToObject = {};
        const dependencyOf = {};
        const todo = [startingObject];
        const visited = {};
    
        while (0 < todo.length) {
            let obj = todo.pop();
            let objName = obj.uniqueName();
            if (! visited[ objName ]) {
                visited[ objName ] = true;
                nameToObject[objName] = obj;
                dependencyRelations(obj).forEach((pair) => {
                    const [from, to] = pair;
                    // It is OK to put things in todo that are visited, we just don't process again.
                    todo.push(from);
                    todo.push(to);
                    if (! dependencyOf[from.uniqueName()]) {
                        dependencyOf[from.uniqueName()] = {}
                    }
                    dependencyOf[from.uniqueName()] = to.uniqueName();
                });
            }
        }
        return [nameToObject, dependencyOf];
    }
    

    这个函数将构建依赖图。但是我们仍然需要先做一个拓扑排序来获得依赖关系。

    function objectsInOrder (nameToObject, dependencyOf) {
        const answer = [];
        visited = {};
    
        // Trick for a recursive function local to my environment.
        let addObject = undefined;
        addObject = function (objName) {
            if (! visited[objName]) {
                visited[objName] = true; // Only process once.
                // Add dependencies
                Object.keys(dependencyOf[objName]).forEach(addObject);
                answer.push(nameToObject[objName]);
            }
        };
        Object.keys(dependencyOf).forEach(addObject);
        return answer;
    }
    

    现在我们有一个对象数组,每个对象只依赖于前面的对象。发送它,然后在另一端依次为每个对象充气。

    【讨论】:

    • 你能解释一下dependencyOf尤其是if (! dependencyOf[from.uniqueName()])
    • 还可以有没有依赖关系的独立对象,也可以有 2 3 ... 断开连接的图,例如 obj1 需要 obj2obj3obj4 需要 obj5 . dependencyInfo(obj1) 不会覆盖obj4obj5。需要为dependencyInfo 函数提供整个模式数组以创建完整的图形(覆盖所有对象)以进行排序
    • 如果bardependencyOffoo 的键,那么您必须先构建bar。 if check 的原因是因为我希望它是散列的散列,所以如果子散列不存在,我想创建它。 JavaScript 可能会也可能不会为您创建它(这称为自动激活),但我切换语言的次数已经足够多,以至于我不想记住这一事实。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多