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

时间:2017-12-07 11:52:58

标签: python mongodb graph pymongo

假设我有一个包含节点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'...}]

1 个答案:

答案 0 :(得分:2)

使用$graphLookup管道阶段。

  • $group - 从childname字段中收集所有可能的值。
  • $addFields - 生成包含根文档的roots字段值的数组。
  • $unwind - 将name数组拆分为单独的文档。
  • $graphLookup - 按照根文档的给定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 } } ]) 字段值收集相关文档。
  • $project - 从结果文档中删除不必要的字段。

查询:

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

结果:

newDict = {'Jan':31, 'Feb':29, 'Mar':31, 'Apr':30, 'May':31, 'Jun':30, 'Jul':31, 'Aug':30}