首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mongodb $graphLookup构建层次结构

Mongodb $graphLookup构建层次结构
EN

Stack Overflow用户
提问于 2019-01-05 00:49:15
回答 1查看 2K关注 0票数 1

我有一个来自mongodb $graphLookup聚合的输出:

代码语言:javascript
复制
db.getCollection('projects').aggregate([
    {
    $lookup: {
      from: "projects",
      localField: "_id",
      foreignField: "parent",
       as: "childrens"
     }
 }
])
代码语言:javascript
复制
{
    "_id" : "1",
    "name" : "Project1",
    "parent" : null,
    "childrens" : [ 
        {
            "_id" : "3",
            "name" : "ProjectForId1",
            "parent" : "1"
        }
    ]
},
{
    "_id" : "3",
    "name" : "ProjectForId1",
    "parent" : "1",
    "childrens" : [ 
        {
            "_id" : "6",
            "name" : "ProjectForId3",
            "parent" : "3"
        }, 
        {
            "_id" : "7",
            "name" : "ProjectForId3",
            "parent" : "3"
        }
    ]
}

我需要在javascript中从这个输出构建层次结构,或者如果可以直接通过查询构建层次结构,所以最后的输出应该如下所示:

代码语言:javascript
复制
{
    "_id" : "1",
    "name" : "Project1",
    "parent" : null,
    "childrens" : [ 
        {
            "_id" : "3",
            "name" : "ProjectForId1",
            "parent" : "1",
            "childrens" : [ 
                {
                    "_id" : "6",
                    "name" : "ProjectForId3",
                    "parent" : "3"
                }, 
                {
                    "_id" : "7",
                    "name" : "ProjectForId3",
                    "parent" : "3"
                }
            ]
        }
    ]
} 

另外,如果有人有勇气帮助再一次通过过滤_id创建层次结构的情况:

对于_id = "1",输出将与上面相同,但是如果_id3,则最终输出应该如下所示:

代码语言:javascript
复制
{
    "_id" : "3",
    "name" : "ProjectForId1",
    "parent" : "1",
    "childrens" : [ 
        {
            "_id" : "6",
            "name" : "ProjectForId3",
            "parent" : "3"
        }, 
        {
            "_id" : "7",
            "name" : "ProjectForId3",
            "parent" : "3"
        }
    ]
}
EN

回答 1

Stack Overflow用户

发布于 2019-01-05 08:19:22

下面的解决方案与我过去的一个答案大致相同,所以您可以得到彻底的解释here

代码语言:javascript
复制
db.projects.aggregate([
    {
        $graphLookup: {
            from: "projects",
            startWith: "$_id",
            connectFromField: "_id",
            connectToField: "parent",
            as: "children",
            maxDepth: 4,
            depthField: "level"
        }
    },
    {
        $unwind: "$children"
    },
    {
        $sort: { "children.level": -1 }
    },
    {
        $group: {
            _id: "$_id",
            children: { $push: "$children" }
        }
    },
    {
        $addFields: {
            children: {
                $reduce: {
                    input: "$children",
                    initialValue: {
                        currentLevel: -1,
                        currentLevelProjects: [],
                        previousLevelProjects: []
                    },
                    in: {
                        $let: {
                            vars: {
                                prev: { 
                                    $cond: [ 
                                        { $eq: [ "$$value.currentLevel", "$$this.level" ] }, 
                                        "$$value.previousLevelProjects", 
                                        "$$value.currentLevelProjects" 
                                    ] 
                                },
                                current: { 
                                    $cond: [ 
                                        { $eq: [ "$$value.currentLevel", "$$this.level" ] }, 
                                        "$$value.currentLevelProjects", 
                                        [] 
                                    ] 
                                }
                            },
                            in: {
                                currentLevel: "$$this.level",
                                previousLevelProjects: "$$prev",
                                currentLevelProjects: {
                                    $concatArrays: [
                                        "$$current", 
                                        [
                                            { $mergeObjects: [ 
                                                "$$this", 
                                                { children: { $filter: { input: "$$prev", as: "e", cond: { $eq: [ "$$e.parent", "$$this._id"  ] } } } } 
                                            ] }
                                        ]
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    {
        $addFields: { children: "$children.currentLevelProjects" }
    },
    {
        $match: {
            _id: "1"
        }
    }
])

最后一个阶段应该是过滤,这样你就可以在这里得到任何深度的数据。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54047977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档