如何在MongoDB中存储/检索树结构?

时间:2016-11-07 09:39:39

标签: mongodb

首先,我知道这篇文章https://docs.mongodb.com/v3.2/applications/data-models-tree-structures/

但是我需要检索多个级别的树结构。 例如,对于数据:

{ doc: "a", children: ["b", "c"] }
{ doc: "b", children: ["d"] }
{ doc: "c", children: ["e"] }
{ doc: "d", children: [] }
{ doc: "e", children: ["f"] }
{ doc: "f", children: [] }

我必须检索doc“a”的完整树:

a
 b
  d
 c
  e
   f

mongoDB可以吗?

2 个答案:

答案 0 :(得分:1)

您可以尝试攻击使用$lookup $unwind 运算符的汇总管道,如下所示:

db.collection.aggregate([
    {
        "$unwind": {
            "path": "$children",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$lookup": {
            "from": "test",
            "localField": "children",
            "foreignField": "doc",
            "as": "child"
        }
    },
    {
        "$unwind": {
            "path": "$child",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$unwind": {
            "path": "$child.children",
            "preserveNullAndEmptyArrays": true
        }
    },    
    {
        "$lookup": {
            "from": "test",
            "localField": "child.children",
            "foreignField": "doc",
            "as": "child.child"
        }
    },
    {
        "$unwind": {
            "path": "$child.child",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$unwind": {
            "path": "$child.child.children",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$lookup": {
            "from": "test",
            "localField": "child.child.children",
            "foreignField": "doc",
            "as": "child.child.child"
        }
    },
    {
        "$unwind": {
            "path": "$child.child.child",
            "preserveNullAndEmptyArrays": true
        }
    },
    {
        "$unwind": {
            "path": "$child.child.child.children",
            "preserveNullAndEmptyArrays": true
        }
    },    
    {
        "$group": {
            "_id": "$doc",
            "children": { "$push": "$child" }
        }
    },
    { "$match": { "_id": "a" } }
])

示例输出

{
    "_id" : "a",
    "children" : [ 
        {
            "_id" : ObjectId("58204f0cd3cda4b4b1adadfb"),
            "doc" : "b",
            "children" : "d",
            "child" : {
                "_id" : ObjectId("58204f0cd3cda4b4b1adadfd"),
                "doc" : "d"
            }
        }, 
        {
            "_id" : ObjectId("58204f0cd3cda4b4b1adadfc"),
            "doc" : "c",
            "children" : "e",
            "child" : {
                "_id" : ObjectId("58204f0cd3cda4b4b1adadfe"),
                "doc" : "e",
                "children" : "f",
                "child" : {
                    "_id" : ObjectId("58204f0cd3cda4b4b1adadff"),
                    "doc" : "f"
                }
            }
        }
    ]
}

答案 1 :(得分:1)

从MongoDB 3.4开始,您可以使用$ graphLookup

该阶段将一个文档的connectFromField与该集合中其他文档的connectToField匹配。然后,对于任何匹配的文档,$ graphLookup使用匹配文档的connectFromField来匹配其他文档的connectToField,并继续直到没有遇到新文档或直到指定深度

https://docs.mongodb.com/master/release-notes/3.4-reference/#pipe._S_graphLookup