You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MongoDB中关联Node与Organisation集合查询父子层级关系?

在MongoDB中关联Node与Organisation集合并查询父子层级关系

根据你的集合结构和层级需求,我们可以通过MongoDB的聚合管道(尤其是$graphLookup递归查询)来整合Organisation和Node的层级,生成带嵌套children的树形结构。以下是具体实现步骤:

整体思路

先递归构建Organisation的完整层级树,再关联对应的Node层级树,最后将Node树挂载到对应的底层Organisation的children中,形成顶层Org→子Org→底层Org→顶层Node→子Node→底层Node的完整链路。

完整聚合查询代码

db.Organisation.aggregate([
  // 1. 递归构建Organisation的层级树
  {
    $graphLookup: {
      from: "Organisation",
      startWith: "$_id",
      connectFromField: "_id",
      connectToField: "_parentOrg",
      as: "children",
      depthField: "depth" // 可选:记录每个节点的层级深度
    }
  },
  // 筛选出顶层Organisation(无_parentOrg字段)
  {
    $match: {
      _parentOrg: { $exists: false }
    }
  },
  // 2. 关联并构建对应Organisation的Node层级树
  {
    $lookup: {
      from: "Node",
      let: { currentOrgId: "$_id" },
      pipeline: [
        // 匹配关联当前Organisation的顶层Node(含_organisation字段)
        {
          $match: {
            $expr: { $eq: ["$_organisation", "$$currentOrgId"] }
          }
        },
        // 递归查询当前Node的所有子Node
        {
          $graphLookup: {
            from: "Node",
            startWith: "$_id",
            connectFromField: "_id",
            connectToField: "_parentNode",
            as: "children"
          }
        },
        // 整理Node的输出结构
        {
          $project: {
            _id: 1,
            name: 1,
            children: {
              $map: {
                input: "$children",
                as: "childNode",
                in: {
                  _id: "$$childNode._id",
                  name: "$$childNode.name",
                  children: "$$childNode.children"
                }
              }
            }
          }
        }
      ],
      as: "linkedNodes"
    }
  },
  // 3. 将Node树整合到Organisation的层级中
  {
    $addFields: {
      children: {
        $map: {
          input: "$children",
          as: "childOrg",
          in: {
            _id: "$$childOrg._id",
            name: "$$childOrg.name",
            children: {
              // 把当前Organisation对应的Node树添加到子节点列表
              $concatArrays: [
                "$$childOrg.children",
                {
                  $filter: {
                    input: "$linkedNodes",
                    cond: { $eq: ["$$this._organisation", "$$childOrg._id"] }
                  }
                }
              ]
            }
          }
        }
      }
    }
  },
  // 4. 整理最终输出字段
  {
    $project: {
      _id: 1,
      name: 1,
      children: 1
    }
  }
])

关键步骤说明

  1. 递归构建Organisation层级:
    使用$graphLookup遍历所有子Organisation,自动生成每个Org的children列表,再通过$match筛选出顶层Org(无_parentOrg)作为树形结构的根节点。

  2. 关联并构建Node层级:
    通过$lookup关联当前Org对应的顶层Node,再对每个Node用$graphLookup递归查询子Node,生成完整的Node树形结构,确保每个Node都带有自己的children列表。

  3. 整合Org与Node层级:
    用$map和$concatArrays将每个底层Organisation对应的Node树添加到该Org的children数组中,让整个层级链完整闭合。

  4. 输出结构整理:
    最后通过$project只保留需要的_id、name、children字段,输出结构统一,方便后续前端构建树形组件。

性能优化建议

  • 给_parentOrg、_parentNode、_organisation这三个字段创建单字段索引,大幅提升递归查询的速度。
  • 如果不需要无限层级,可以在$graphLookup中添加maxDepth参数限制递归深度。

内容的提问来源于stack exchange,提问作者Yiffany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 01:24:57