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

MongoDB多层$group聚合如何输出嵌套文档而非数组

问题原因

你之前的写法出现内容截断是因为$arrayToObject要求数组中每个元素的k值唯一,同一个type的多条数据会被后续同key的条目覆盖,只会保留最后一条;多余的data字段是因为你没有将嵌套的结构提升到文档根层级。

纯聚合管道实现方案(无需JS,性能友好)

整个 pipeline 均使用MongoDB原生聚合算子,计算效率远高于JS遍历,适合低配置服务器处理大数据量:

db.collection.aggregate([
  // 第一步:按三层维度先做最细粒度分组,提前压缩数据量
  {
    $group: {
      _id: {
        class: "$class",
        type: "$type",
        color: "$color"
      },
      docs: { $push: "$$ROOT" } // 保留所有字段,不需要手动逐一指定
    }
  },
  // 第二步:按class+type分组,生成type下color到文档数组的映射
  {
    $group: {
      _id: {
        class: "$_id.class",
        type: "$_id.type"
      },
      colorMap: { $push: { k: "$_id.color", v: "$docs" } }
    }
  },
  {
    $addFields: {
      colorMap: { $arrayToObject: "$colorMap" }
    }
  },
  // 第三步:按最上层class分组,生成class下type到color映射的结构
  {
    $group: {
      _id: "$_id.class",
      typeMap: { $push: { k: "$_id.type", v: "$colorMap" } }
    }
  },
  {
    $addFields: {
      typeMap: { $arrayToObject: "$typeMap" }
    }
  },
  // 第四步:将结构提升到根层级,去掉多余的嵌套字段
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [ { _id: "$_id" }, "$typeMap" ]
      }
    }
  }
], { allowDiskUse: true }) // 开启磁盘暂存,避免低内存服务器出现溢出报错

性能优化建议

  • 提前为class、type、color字段建立复合索引,可大幅加快分组排序速度
  • 若不需要保留原文档的所有字段,可在第一步$push时手动指定需要的字段,减少内存占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:48:04