使用树结构在MongoDb中获取祖先

使用树结构在MongoDb中获取祖先,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有以下代表目录结构的集合 我想编写一个聚合查询,它将返回从某个点开始的所有子目录ID 例如: 从根开始:结果:child_A,child_B,child_A_1 从child_a开始:结果:child_a_1 我在Mongo4.2中根据创建了以下查询,但无法成功运行 [{ $match: { _id: ObjectId('5de7a00bf3663d0805644b91') } }, { $graphLookup: { from: 'do

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

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

例如:

从根开始:结果:child_A,child_B,child_A_1

从child_a开始:结果:child_a_1

我在Mongo4.2中根据创建了以下查询,但无法成功运行

[{
    $match: {
        _id: ObjectId('5de7a00bf3663d0805644b91')
    }
}, {
    $graphLookup: {
        from: 'documents',
        startWith: '$_id',
        connectFromField: '_id',
        connectToField: 'parentId',
        as: 'hierarchy'
    }
}]
我如何解决这个问题?

这是一个非常重要的解决方案

要求

1我们需要添加额外的字段,我们称之为level,它指示文档在层次结构中的位置

|root        0
|-child A    1
|--child A_1 2
|-child B    1
2我们需要定义以前的层次结构深度,例如:max 3

限度

为了从特定级别进行筛选,我们需要修改root和children$match值

确保始终处于层次结构级别:

root     - 0
children - 1

root     - 1
children - 2  
解决方案

最大深度:3 |最大深度:4

解释

通过$facet,我们定义了层次结构。仅根目录下的所有根目录。children包含具有级别1+子代的所有子代

我们使用$filter按parentId合并根和子项

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

链接

您的查询按预期工作:
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"
    }
  }
])