gpt4 book ai didi

MongoDB 的 $graphLookup 试图获取树结构

转载 作者:可可西里 更新时间:2023-11-01 09:10:32 25 4
gpt4 key购买 nike

我正在尝试使用新的 MongoDB v3.4 $graphLookup 聚合管道。我有这个简单的树集合,有一些节点和一个父 DBRef:

{ "_id" : ObjectId("59380657bbdbfb36c18a80f2"), "name" : "Root node 1" },
{ "_id" : ObjectId("5938068abbdbfb36c18a80f5"), "name" : "Child 1.1", "parent" : ObjectId("59380657bbdbfb36c18a80f2") },
{ "_id" : ObjectId("593806b0bbdbfb36c18a80f7"), "name" : "Subchild 1.1.1", "parent" : ObjectId("5938068abbdbfb36c18a80f5") },
{ "_id" : ObjectId("5938068abbdbfb36c18a80f6"), "name" : "Child 1.2", "parent" : ObjectId("59380657bbdbfb36c18a80f2") },
{ "_id" : ObjectId("59380657bbdbfb36c18a80f3"), "name" : "Root node 2" }

我想得到这种树结构:

- Root node 1
- Child 1.1
- Subchild 1.1.1
- Child 1.2
- Root node 2

因此,我正在尝试使用新的 $graphLookup 聚合管道,如下所示:

db.getCollection('tree').aggregate([
{ $match: { parent: { $exists: false } } },
{
$graphLookup: {
from: "tree",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parent",
as: "children"
}
},
{ $sort: { name: 1 } }
])

但我的问题是我在一个集合中得到了“根节点 1”的所有子节点:

{
"_id" : ObjectId("59380657bbdbfb36c18a80f2"),
"name" : "Root node 1",
"children" : [
{ "_id" : ObjectId("593806b0bbdbfb36c18a80f7"), "name" : "Subchild 1.1.1", "parent" : ObjectId("5938068abbdbfb36c18a80f5") },
{ "_id" : ObjectId("5938068abbdbfb36c18a80f6"), "name" : "Child 1.2", "parent" : ObjectId("59380657bbdbfb36c18a80f2") },
{ "_id" : ObjectId("5938068abbdbfb36c18a80f5"), "name" : "Child 1.1", "parent" : ObjectId("59380657bbdbfb36c18a80f2") }
]
},
{
"_id" : ObjectId("59380657bbdbfb36c18a80f3"),
"name" : "Root node 2",
"children" : [ ]
}

我不知道如何递归查找子项以在“Child 1.1”的子项集合中获取“Subchild 1.1.1”。我正在寻找任何建议。谢谢:)

最佳答案

$graphLookup不产生依赖关系的层次结构——它对连接的文档执行递归搜索,但结果被展平到一维数组中。这是文档中的引述:

For each matching document, $graphLookup takes the value of the _id and checks every document in the tree collection for a matching parent value. For each match, $graphLookup adds the matching document in the from collection to an array children. This step continues recursively until no more matching documents are found, or until the operation reaches a recursion depth specified by the maxDepth parameter.

即它以递归方式搜索相关文档,但无论子文档位于多“深”,每个找到的文档都会添加到父文档的相同子数组中。


注意 - 您看不到 Child 1.1 及其连接的 Subchild 1.1.1,因为您在 match 阶段过滤掉了这些文档:

{ $match: { parent: { $exists: false } } }

仅选择没有父节点的文档 - “Root node 1”“Root node 2”。如果您将删除此过滤器,则将返回所有其他具有其从属层次结构的文档:

{
"name" : "Child 1.1",
"children" : [
{ "name" : "Subchild 1.1.1" }
]
},
{
"name" : "Child 1.2"
"children" : []
},
{
"name" : "Root node 1",
"children" : [
{ "name" : "Subchild 1.1.1" },
{ "name" : "Child 1.2" },
{ "name" : "Child 1.1" }
]
},
{
"name" : "Root node 2",
"children" : []
},
{
"name" : "Subchild 1.1.1"
"children" : []
}

如果您不想在单个 child 数组中混合来自不同“深度”树的 child ,那么请查看文档中有趣的评论

Setting the maxDepth field to 0 is equivalent to a non-recursive $lookup search stage.

这意味着每个文档都会将其所有直接子项放入 children 数组中,之后查找将停止而无需任何进一步的递归搜索。输出将是

{
"name" : "Child 1.1",
"children" : [
{ "name" : "Subchild 1.1.1" }
]
},
{
"name" : "Child 1.2"
"children" : []
},
{
"name" : "Root node 1",
"children" : [
{ "name" : "Child 1.2" },
{ "name" : "Child 1.1" }
]
},
{
"name" : "Root node 2",
"children" : []
},
{
"name" : "Subchild 1.1.1"
"children" : []
}

关于MongoDB 的 $graphLookup 试图获取树结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44415646/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com