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

MongoDB中$graphLookup与$lookup的选择及层级数据聚合实现

嘿,刚好能帮你理清这俩MongoDB聚合操作符的区别,还能直接给你搞定数据嵌套的方案~

先搞懂$lookup vs $graphLookup的适用场景
  • $lookup:是平级关联工具,适合处理一对一、一对多的非层级关系(比如订单关联用户信息),只能关联一层数据,没法递归查询子节点的子节点。
  • $graphLookup:是层级/递归关联工具,专门用来处理树形结构数据(比如部门层级、商品分类目录),可以递归查询任意层级的后代节点,直到没有子节点为止。
针对你的需求:用$lookup快速实现两层嵌套

你的数据只有两层(根节点parentId=0,子节点直接关联根节点的cid),用$lookup就足够简单高效,直接看聚合代码:

// 替换成你的集合名称,比如叫categories
db.categories.aggregate([
  // 第一步:先筛选出所有根节点(parentId为0的文档)
  { $match: { parentId: 0 } },
  // 第二步:关联子节点,把匹配到的子文档放入children数组
  {
    $lookup: {
      from: "categories", // 要关联的集合名称,和当前集合一致
      localField: "cid", // 当前文档用来匹配的字段(父节点的cid)
      foreignField: "parentId", // 关联集合中用来匹配的字段(子节点的parentId)
      as: "children" // 存储子文档的字段名,就是你要的children
    }
  }
])

执行这段代码后,就能得到你想要的结果:每个根节点都会带上对应的子节点数组,完全符合你的预期。

如果是多层树形结构?用$graphLookup递归查询

假设你的数据不止两层(比如cid=11还有子节点parentId=11),这时候$lookup就不够用了,得用$graphLookup来递归捞所有后代:

db.categories.aggregate([
  { $match: { parentId: 0 } },
  {
    $graphLookup: {
      from: "categories",
      startWith: "$cid", // 递归的起始值:当前根节点的cid
      connectFromField: "cid", // 每一层递归时,用来匹配下一级的字段(当前节点的cid)
      connectToField: "parentId", // 下一级节点中用来匹配的字段(子节点的parentId)
      as: "children", // 存储所有后代节点的数组
      maxDepth: 2 // 可选:指定最大递归深度,避免无限递归;不写则默认递归到没有子节点
    }
  }
])

这个操作会把根节点下所有层级的子节点都捞出来放到children数组里,适合复杂的树形结构场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:18:00