如何使用Sequelize填充树

时间:2015-08-11 22:16:13

标签: node.js sequelize.js

我希望以高效且一致的方式填充目录。 (ids应始终相同) 使用引用自身的模型来构建多树结构:

var Category = sequelize.define("Category", {
  name: DataTypes.STRING
}, {
  timestamps: false,
  classMethods: {
    associate: function(models) {
      Category.hasMany(models.Category, {
        as: 'Children',
        foreignKey: 'ParentId',
        useJunctionTable: false
      });
    }
  }
});

数据示例:

var categories = [
{ name: "Menu A", Children: [
  { name: "Sub 1"},
  { name: "Sub 2", Children: [
    { name: "Element 1" },
    { name: "Element 2" }
  ]},
]}
];

ATM我可以创建所有类别:

var process = function (node) {
  node.forEach(function (value, index, array) {
    models.Category.create(value);
    if(value.Children){
      process(value.Children);
    }
  });
  return node;
}

process(categories);

但我错过了模特协会。

3 个答案:

答案 0 :(得分:1)

我使用模块https://github.com/domasx2/sequelize-fixtures来实现与您类似的东西。

使用此模块,您可以使用固定ID和关联加载数据库中的数据:

[
    {
        "model": "Owner",
        "data": {
            "id": 11,
            "name": "John Doe",
            "city": "Vilnius"
        }
    },
    {
        "model": "Car",
        "data": {
            "id": 203,
            "make": "Ford",
            "owner": 11
        }
    }
]

希望这有帮助

答案 1 :(得分:1)

不是完美的解决方案,(我对承诺并不擅长),但这是一种快速而又肮脏的方式:

, Childs: []}添加到所有节点。

用嵌套横冲直撞来处理它们!

function processNode(node) {
  models.Category.create(node).then(function(created){
    node.Childs.forEach(function(child){
      models.Category.create(child).then(function(theChild) {
        created.addChild(theChild);
        child.Childs.forEach(function(grandChild){
          models.Category.create(grandChild).then(function(theGrandChild){
            theChild.addChild(theGrandChild);
            grandChild.Childs.forEach(function(grandGrandChild){
              models.Category.create(grandGrandChild).then(function(theGrandGrandChild){
                theGrandChild.addChild(theGrandGrandChild);
              })
            })
          })
        })
      })
    })
  });
}

categories.forEach(function(mainCategory){
    processNode(mainCategory);
});

丑陋,但是做到了,仍然在寻找一种很好的方法。

答案 2 :(得分:1)

根据其描述,还有另一个Node Package可以实现此目标,称为 sequelize-hierarchy

“关系数据库不太善于处理嵌套层次结构.....

要将层次结构存储在数据库中,通常的方法是为每个记录赋予一个ParentID字段,该字段指出哪个记录​​位于其上一级。

获取任何记录的父项或子项很容易,但是如果要从数据库中检索整个树/层次结构,则需要多个查询,以递归方式获取层次结构的每个级别。对于大树结构来说,这是一个漫长的过程,而且很烦人。

此Sequelize插件可解决此问题。”

您可以找到它here