[英]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-从name
和child
字段中收集所有可能的值。 $addFields
- generates the array with name
field values of the root documents. $addFields
生成具有根文档的name
字段值的数组。 $unwind
- splits roots
array into seperated documents. $unwind
将roots
数组拆分为单独的文档。 $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.