Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何对mongodb中连接的文档(图的节点)进行分组_Python_Mongodb_Graph_Pymongo - Fatal编程技术网

Python 如何对mongodb中连接的文档(图的节点)进行分组

Python 如何对mongodb中连接的文档(图的节点)进行分组,python,mongodb,graph,pymongo,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'...}, {n

假设我有一个节点为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'...}]
使用管道阶段

  • -从
    name
    child
    字段收集所有可能的值
  • -使用根文档的
    name
    字段值生成数组
  • -将
    数组拆分为单独的文档
  • -根据根文档的给定
    名称
    字段值收集相关文档
  • -从结果文档中删除不必要的字段
查询:

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"
        }
    ]
}
使用管道阶段

  • -从
    name
    child
    字段收集所有可能的值
  • -使用根文档的
    name
    字段值生成数组
  • -将
    数组拆分为单独的文档
  • -根据根文档的给定
    名称
    字段值收集相关文档
  • -从结果文档中删除不必要的字段
查询:

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
将是better@AlexBlex是的,你说得对,谢谢你的帮助。我更新了我的答案。谢谢。。你也能帮我一下吗?
$addToSet
代替
$push
better@AlexBlex是的,你说得对,谢谢你的帮助。我更新了我的答案。谢谢。。你也能帮我做这个吗。。