MongoDB的$ graphLookup尝试获取树形结构 [英] MongoDB's $graphLookup trying to get a tree structure

查看:142
本文介绍了MongoDB的$ graphLookup尝试获取树形结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to work with the new MongoDB v3.4 $graphLookup aggregation pipeline. I have this simple tree collection, with some nodes and a parent 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" }

我想得到这种树形结构:

I would like to get this kind of tree structure:

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

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

So, I'm trying to work with the new $graphLookup aggregation pipeline, like this:

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

但是我的问题是,我在一个集合中获得了根节点1"的所有子元素:

But my issue is that I get all child of "Root node 1" in one collection:

{
    "_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" : [ ]
}

我不知道如何递归查找子级以在子级1.1"的子级集合中获得子级1.1.1". 我正在寻找任何建议.谢谢:)

I have no idea how to lookup children recursively to get "Subchild 1.1.1" in the children collection of "Child 1.1". I'm looking for any suggestions. Thanks :)

推荐答案

$ graphLookup 不会生成依赖关系的层次结构-它对连接的文档执行递归搜索,但是结果被展平到一维数组中.这是文档中的报价:

$graphLookup is not producing the hierarchy of dependencies - it performs a recursive search of connected documents, but results are flattened into the single-dimension array. Here is the quote from the documentation:

对于每个匹配的文档,$ graphLookup取值为 _id 并检查集合中的每个文档是否 匹配的父级值.对于每个匹配项,$ graphLookup会添加 将from集合中的文档匹配到数组子项.此步骤递归地继续进行,直到不再 找到匹配的文档,或者直到操作达到 maxDepth参数指定的递归深度.

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.

即它会递归搜索相关文档,但是无论子文档的位置有多深",每个找到的文档都会添加到父文档的相同子数组中.

I.e. it searches for dependent documents recursively, but each found document is added to same children array of the parent document no matter how 'deep' the child is located.

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

Note - you don't see Child 1.1 with its connected Subchild 1.1.1 because you are filtering out these documents in match stage:

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

仅选择没有父级的文档-"Root node 1""Root node 2".如果您要删除此过滤器,则将返回所有其他文件及其从属文件的层次结构:

that selects only documents which don't have a parent - "Root node 1" and "Root node 2". If you will remove this filter, then all other documents with the hierarchy of their dependants will be returned:

{
    "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" : []
}


如果您不想将来自不同深度"树的子级混合在单个子级数组中,请查看文档中有趣的注释


If you don't want to mix children from different 'depth' of tree in single children array, then take a look at interesting comment in documentation

将maxDepth字段设置为0等效于非递归 $ lookup搜索阶段.

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

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

It means that each document will get all its direct children into the children array, and after that lookup will stop without any further recursive search. Output will be

{
    "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尝试获取树形结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆