使用树结构在MongoDb中获取祖先 [英] Getting ancestors in MongoDb using tree structure

查看:77
本文介绍了使用树结构在MongoDb中获取祖先的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下表示目录结构的集合.

I have the following collection representing the directory structure.

我想编写一个聚合查询,该查询将返回从某个点开始的所有子目录ID .

I'd like to write an aggregation query that will return all child directory IDs starting from a certain point.

例如:

  • root 开始:结果: child_A child_B child_A_1

child_a 开始:结果: child_A_1

我已经根据文档,但是我无法成功运行它.

I've created the following query (in Mongo 4.2) according to the docs, but I'm unable to run it successfully.

[{
    $match: {
        _id: ObjectId('5de7a00bf3663d0805644b91')
    }
}, {
    $graphLookup: {
        from: 'documents',
        startWith: '$_id',
        connectFromField: '_id',
        connectToField: 'parentId',
        as: 'hierarchy'
    }
}]

我该如何解决这个问题?

How can I solve that issue?

推荐答案

这是不平凡的解决方案.

要求

1我们需要添加额外的字段(我们将其称为 level ),该字段指示文档在层次结构中的位置.

1 We need to add extra field (let's call it level) which indicates where document is located inside hierarchy.

|root        0
|-child A    1
|--child A_1 2
|-child B    1

2我们需要定义先前的层次深度(例如:最大值3)

2 We need to define previously hierarchy depth (for instance: max 3)

限制

为了从特定级别进行过滤,我们需要修改 root children $ match 值.

In order to filter from specific level, we need to modify root and children $match values.

始终确保层次结构级别:

Ensure always hierarchy level:

root     - 0
children - 1

root     - 1
children - 2  

解决方案

db.documents.aggregate([
  {
    $facet: {
      root: [
        {
          $match: {
            level: 0
          }
        }
      ],
      children: [
        {
          $match: {
            level: 1
          }
        },
        {
          $graphLookup: {
            from: "documents",
            startWith: "$_id",
            connectFromField: "_id",
            connectToField: "parentId",
            maxDepth: 0,
            as: "hierarchy"
          }
        },
        {
          $sort: {
            _id: 1
          }
        }
      ]
    }
  },
  {
    $unwind: "$root"
  },
  {
    $project: {
      "root._id": 1,
      "root.name": 1,
      "root.level": 1,
      "root.hierarchy": {
        $filter: {
          input: "$children",
          as: "sub_level",
          cond: {
            $eq: [
              "$$sub_level.parentId",
              "$root._id"
            ]
          }
        }
      }
    }
  },
  {
    $replaceRoot: {
      newRoot: "$root"
    }
  }
])

MongoPlayground (最大深度:3)| MongoPlayground (最大深度:4)

MongoPlayground (max depth: 3) | MongoPlayground (max depth: 4)

EXPLANATION

  1. 使用 $ facet 定义级别结构. root 仅是所有根目录. children 包含所有1级以上的子级及其子代.

  1. With $facet we define level structure. root all root directory only. children contains all children with level 1 + children descendants.

我们通过 parentId

使用 $ project $ replaceRoot ,我们返回原始结构.

With $project and $replaceRoot we return original structure.

链接

https://docs.mongodb.com/manual/reference/运算符/聚合/方面/
https://docs.mongodb.com/manual/reference/operator/aggregation/filter/
https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/

这篇关于使用树结构在MongoDb中获取祖先的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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