使用mongoose从MongoDB中检索分层数据的方法

时间:2015-07-07 10:20:03

标签: node.js mongodb mongoose hierarchical-data

我使用Mongodb使用Mongoose存储一些数据。我想知道是否有开箱即用的功能来获取分层数据:

假设我有一个名为Books的文件。书籍的子名称为Programming。编程有两个孩子Databases & Languages&等等。有关层次结构的更多信息,请参见下图。

db.categories.insert( { _id: "MongoDB", children: [] } )
db.categories.insert( { _id: "dbm", children: [] } )
db.categories.insert( { _id: "Databases", children: [ "MongoDB", "dbm" ] } )
db.categories.insert( { _id: "Languages", children: [] } )
db.categories.insert( { _id: "Programming", children: [ "Databases", "Languages" ] } )
db.categories.insert( { _id: "Books", children: [ "Programming" ] } )

enter image description here

有没有办法使用Moongose中的一些开箱即用功能来检索分层数据?我应该能够得到这样的输出

{
    name: "books",
    nodes: [
        {
            name: "Programming",
            nodes: [
                {
                    name: "Databases",
                    nodes: [
                        {
                            name: "MonogoDB"
                        },
                        {
                            name: "dbm"
                        }
                    ]
                },
                {
                    name: "Languages"
                }
            ]
        }
    ]
}

到目前为止,我已经尝试了这个,但由于Mongoose的asyn性质,我无法产生预期的结果。

  //Find all top level documents. Currently I only have books as top level document
    //But in future there can be multiple top level doc. 
    //All top level doc will have parent as null
myDoc.find({
    parent: null
  }, function (err, topics) {
    if (err) {
      return handleError(res, err);
    }
    var docTree = [];
    _.each(document, function(parentDoc) {
       var doc = {};
       doc.text = parentDoc.name;
      doc.nodes = [];
      _.each(parentDoc.children, function(child) {
        doc.nodes.push(processChildren(child));
      });
      docTree.push(doc);

    });



function processChildren(child) {

  myDoc.findById(child, function (err,item) {
    var doc = {};
    doc.name = item._doc.name;
    doc.nodes = [];
    if (item._doc.children === null) {
      return topic;
    } else {
      _.each(item._doc.children, function (chld) {
        processChildren(chld);
      });
    }
    return doc;
  });

};

1 个答案:

答案 0 :(得分:0)

如果您使用embedded docs,您将获得开箱即用的数据。但是嵌入式文档必须是一个数组,并且它们实际上并不存储在MongoDB中它们自己的集合中(它们只是一个猫鼬层)所以你基本上只是在mongoDB中创建/存储一个大文档被关注到。

或者您可以使用referenced documents并使用deep-populate这样的插件,这样可以避免手动循环以获得所需的输出。