简体   繁体   English

如何从mongodb分组连接的文档(图的节点)

[英]How to group connected documents (nodes of graph ) from mongodb

Assume that I have a one-way graph with nodes A,B,C,D,E such that 假设我有一个带有节点A,B,C,D,E的单向图,这样

A->B->C is a connected component, A-> B-> C是连接的组件,

D->E is another connected component. D-> E是另一个连接的组件。

Nodes are saved in MongoDB as documents 节点作为文档保存在MongoDB中

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

How to get all connected components? 如何获得所有连接的组件?

Expected result: 2 groups 预期结果:2组

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

Use $graphLookup pipeline stage. 使用$graphLookup管道阶段。

  • $group - collects all possible values from the name and child fields. $group group-从namechild字段中收集所有可能的值。
  • $addFields - generates the array with name field values of the root documents. $addFields生成具有根文档的name字段值的数组。
  • $unwind - splits roots array into seperated documents. $unwindroots数组拆分为单独的文档。
  • $graphLookup - collects related documents by given name field value of the root document. $graphLookup通过根文档的给定name字段值收集相关文档。
  • $project - removes the not necessary fieldss from the result documents. $project project-从结果文档中删除不必要的字段。

Query: 查询:

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
        }
    }
])

Result: 结果:

/* 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"
        }
    ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM