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

如何在MongoDB同集合中按_id聚合多级子分类数据

实现MongoDB分类数据的多级嵌套聚合

要将扁平的分类数据转换为最多7级的嵌套子分类结构,$graphLookup是最适合的方案——它专门用于处理树形/层级结构的递归查询,比手动多次$lookup更高效简洁。

聚合管道实现代码

假设你的集合名为categories,执行以下聚合操作:

db.categories.aggregate([
  // 筛选根分类(无父级的顶层分类)
  { $match: { parentCategory: null } },
  // 递归查询所有子分类,最多支持6层递归(最终形成7级结构)
  {
    $graphLookup: {
      from: "categories",
      startWith: "$_id",
      connectFromField: "_id",
      connectToField: "parentCategory",
      as: "subCategories",
      maxDepth: 6,
      depthField: "level"
    }
  },
  // 将扁平的子分类列表转换为嵌套结构
  {
    $set: {
      subCategories: {
        $map: {
          input: "$subCategories",
          as: "sub",
          in: {
            _id: "$$sub._id",
            name: "$$sub.name",
            subCategories: {
              $filter: {
                input: "$$sub.subCategories",
                as: "child",
                cond: { $eq: ["$$child.level", { $add: ["$$sub.level", 1] }] }
              }
            }
          }
        }
      }
    }
  },
  // 移除不需要的层级标记字段
  { $unset: ["subCategories.level"] }
])

代码说明

  1. $match阶段:先过滤出所有根分类(parentCategory: null),作为嵌套结构的顶层节点。
  2. $graphLookup阶段(核心):
    • from:指定要查询的集合名;
    • startWith:从当前根分类的_id开始,递归查找子节点;
    • connectFromField/connectToField:定义父子关联规则(子分类的parentCategory等于父分类的_id);
    • maxDepth: 6:允许最多6次递归,加上根节点刚好形成7级结构;
    • depthField:记录每个节点的层级,用于后续整理嵌套关系。
  3. $set+$map阶段:将$graphLookup返回的扁平子分类数组,按层级转换为嵌套的subCategories结构。
  4. $unset阶段:清理掉临时的level字段,得到干净的嵌套结果。

替代方案(不推荐)

如果因版本限制无法使用$graphLookup,可以手动多次嵌套$lookup,但代码会非常冗长(需要写6次$lookup对应7级结构),且性能远不如递归查询:

db.categories.aggregate([
  { $match: { parentCategory: null } },
  // 第1级子分类
  {
    $lookup: {
      from: "categories",
      localField: "_id",
      foreignField: "parentCategory",
      as: "subCategories"
    }
  },
  // 第2级子分类
  { $unwind: { path: "$subCategories", preserveNullAndEmptyArrays: true } },
  {
    $lookup: {
      from: "categories",
      localField: "subCategories._id",
      foreignField: "parentCategory",
      as: "subCategories.subCategories"
    }
  },
  // 重复上述unwind+lookup步骤,直到第7级
  {
    $group: {
      _id: "$_id",
      name: { $first: "$name" },
      subCategories: { $push: "$subCategories" }
    }
  }
])

结果验证

针对你提供的测试数据,执行第一个聚合管道后,会得到完全符合预期的嵌套结构:

[
  {
    "_id": "100",
    "name": "1",
    "subCategories": [
      {
        "_id": "101",
        "name": "2",
        "subCategories": [
          { "_id": "103", "name": "3" }
        ]
      },
      { "_id": "104", "name": "4" }
    ]
  }
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:32:07