【问题标题】:How to group connected documents (nodes of graph ) from mongodb如何从 mongodb 对连接的文档(图的节点)进行分组
【发布时间】:2018-05-21 12:42:11
【问题描述】:

假设我有一个带有节点 A、B、C、D、E 的单向图

A->B->C 是连通分量,

D->E 是另一个连通分量。

节点作为文档保存在 MongoDB 中

{name:'A', child: 'B'}, {name:'B', child: 'C'}, {name:'C'},
{name:'D', child: 'E'}, {name:'E'}

如何获取所有连接的组件?

预期结果:2 组

[{name:'A'...},{name:'B'...}, {name:'C'...}],[{name:'D'...}, {name:'E'...}]

【问题讨论】:

    标签: python mongodb graph pymongo


    【解决方案1】:

    使用$graphLookup流水线阶段。

    • $group - 从 name 和 child 字段中收集所有可能的值。
    • $addFields - 使用根文档的 name 字段值生成数组。
    • $unwind - 将 roots 数组拆分为单独的文档。
    • $graphLookup - 通过给定的根文档的name 字段值收集相关文档。
    • $project - 从结果文档中删除不必要的字段。

    查询:

    db.getCollection('t').aggregate([
        {
            $group: {
                _id: null,
                names: { $addToSet: "$name" },
                childs: { $addToSet: "$child" }
            }
        },
        {
            $addFields: {
                roots: { $setDifference: ["$names", "$childs"] }
            }
        },
        { $unwind: "$roots" },
        {
            $graphLookup: {
                from: "t",
                startWith: "$roots",
                connectFromField: "child",
                connectToField: "name",
                as: "related"
            }
        },
        {
            $project: {
                "related": 1,
                "_id": 0
            }
        }
    ])
    

    结果:

    /* 1 */
    {
        "related" : [ 
            {
                "_id" : ObjectId("5a29316a545eb40950c33bc8"),
                "name" : "C"
            }, 
            {
                "_id" : ObjectId("5a29316a545eb40950c33bc7"),
                "name" : "B",
                "child" : "C"
            }, 
            {
                "_id" : ObjectId("5a29316a545eb40950c33bc6"),
                "name" : "A",
                "child" : "B"
            }
        ]
    }
    
    /* 2 */
    {
        "related" : [ 
            {
                "_id" : ObjectId("5a29316a545eb40950c33bca"),
                "name" : "E"
            }, 
            {
                "_id" : ObjectId("5a29316a545eb40950c33bc9"),
                "name" : "D",
                "child" : "E"
            }
        ]
    }
    

    【讨论】:

    • $addToSet 而不是 $push 会更好
    • @AlexBlex 是的,你是对的,谢谢你的帮助。我更新了我的答案。
    • 谢谢..你能帮我解决这个问题吗..stackoverflow.com/q/47689664/5774004
    猜你喜欢
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 2017-10-24
    • 2015-05-17
    • 1970-01-01
    相关资源
    最近更新 更多