Python 如何对mongodb中连接的文档(图的节点)进行分组
假设我有一个节点为a,B,C,D,E的单向图 A->B->C是一个连接的组件 D->E是另一个连接的组件 节点作为文档保存在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
{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是的,你说得对,谢谢你的帮助。我更新了我的答案。谢谢。。你也能帮我做这个吗。。