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

如何使用MongoDB的$graphLookup获取树形结构所有递归子节点

MongoDB递归查询嵌套树形层级结构实现方案

这个需求完全可以在MongoDB中实现。你当前使用$graphLookup已经可以拉取到所有层级的子孙节点,只是默认返回的是平级数组,需要额外增加聚合阶段将平级数据拼装为嵌套树形结构即可。

第一步:修正原有查询的问题

你原有查询的第一个匹配阶段语法有误,缺少$match操作符,同时查询子孙节点的$graphLookup参数配置错误,导致只能查到一级子节点:

// 错误的匹配阶段写法
{
  name: "Eliot"
}
// 正确写法需要包裹$match
{
  $match: { name: "Eliot" }
}

第二步:完整聚合查询语句

以下是可以直接返回嵌套树形结构的完整聚合语句,适配MongoDB 4.4及以上版本:

db.xmantree.aggregate([
  // 1. 匹配目标根节点
  { $match: { name: "Eliot" } },
  // 2. 递归查询所有层级的子孙节点
  {
    $graphLookup: {
      from: "xmantree",
      startWith: "$_id",
      connectFromField: "_id", // 当前节点的_id作为下一级的parentId匹配条件
      connectToField: "parentId",
      as: "allDescendants",
      // 可选:限制递归深度,比如最多查3级就写maxDepth:2(深度从0开始计数)
      // maxDepth: 2
    }
  },
  // 3. 递归查询所有父节点(和你原有逻辑一致)
  {
    $graphLookup: {
      from: "xmantree",
      startWith: "$parentId",
      connectFromField: "parentId",
      connectToField: "_id",
      as: "parents"
    }
  },
  // 4. 自定义函数将平级的子孙节点拼装为嵌套树形结构
  {
    $addFields: {
      children: {
        $function: {
          body: function(rootId, descendants) {
            // 递归构建树形结构的工具函数
            const buildTree = (parentId) => {
              return descendants
                .filter(item => item.parentId === parentId)
                .map(item => ({
                  ...item,
                  children: buildTree(item._id)
                }))
            }
            return buildTree(rootId)
          },
          args: ["$_id", "$allDescendants"],
          lang: "js"
        }
      }
    }
  },
  // 可选:移除临时存储所有子孙的平级字段
  { $unset: "allDescendants" }
])

运行结果说明

执行上述查询后,你将得到符合预期的嵌套结构,每一级子节点都会自动携带自己的children字段,示例输出如下:

{
  "_id" : 2,
  "name" : "Eliot",
  "parentId" : 1,
  "parents" : [ { "_id" : 1, "name" : "Dev" } ],
  "children" : [
    {
      "_id" : 3,
      "name" : "Ron",
      "parentId" : 2,
      "children" : [
        { "_id" : 5, "name" : "Asya", "parentId" : 3, "children" : [ ] }
      ]
    },
    {
      "_id" : 4,
      "name" : "Andrew",
      "parentId" : 2,
      "children" : [
        { "_id" : 6, "name" : "Dan", "parentId" : 4, "children" : [ ] }
      ]
    }
  ]
}

如果你使用的是MongoDB 4.4以下版本,不支持$function,可以在查询得到平级的allDescendants数组后,在应用层做树形结构拼装,逻辑和上述函数中的buildTree逻辑完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 00:45:03