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

如何在MongoDB中对含嵌套对象数组的多文档执行分组聚合

MongoDB聚合实现方案

核心思路

  • 第一阶段:全局分组聚合,先累加所有文档scalar字段的总和,同时收集所有文档的array、array2元素合并为单个数组
  • 第二阶段:对合并后的array、array2分别用$reduce算子按key分组,对同key的value求和

完整聚合查询代码

db.collection.aggregate([
  // 阶段1:全局分组,聚合基础数据
  {
    $group: {
      _id: null,
      scalar: { $sum: "$scalar" },
      allArray: { $push: "$array" },
      allArray2: { $push: "$array2" }
    }
  },
  // 阶段2:把分组得到的二维数组合并为一维数组,方便后续处理
  {
    $project: {
      _id: 0,
      scalar: 1,
      allArray: { $concatArrays: "$allArray" },
      allArray2: { $concatArrays: "$allArray2" }
    }
  },
  // 阶段3:用$reduce对两个数组分别按key求和
  {
    $project: {
      scalar: 1,
      array: {
        $reduce: {
          input: "$allArray",
          initialValue: [],
          in: {
            $let: {
              vars: {
                // 查找当前累加数组中是否存在和当前元素key相同的项
                existingIndex: { $indexOfArray: ["$$value.key", "$$this.key"] }
              },
              in: {
                $cond: {
                  // 存在同key项则累加value
                  if: { $ne: ["$$existingIndex", -1] },
                  then: {
                    $concatArrays: [
                      { $slice: ["$$value", "$$existingIndex"] },
                      [
                        {
                          key: "$$this.key",
                          value: { $sum: [{ $arrayElemAt: ["$$value.value", "$$existingIndex"] }, "$$this.value"] }
                        }
                      ],
                      { $slice: ["$$value", { $add: ["$$existingIndex", 1] }, { $size: "$$value" }] }
                    ]
                  },
                  // 不存在同key项则直接追加
                  else: { $concatArrays: ["$$value", ["$$this"]] }
                }
              }
            }
          }
        }
      },
      // array2处理逻辑和array完全一致,仅替换输入数组即可
      array2: {
        $reduce: {
          input: "$allArray2",
          initialValue: [],
          in: {
            $let: {
              vars: {
                existingIndex: { $indexOfArray: ["$$value.key", "$$this.key"] }
              },
              in: {
                $cond: {
                  if: { $ne: ["$$existingIndex", -1] },
                  then: {
                    $concatArrays: [
                      { $slice: ["$$value", "$$existingIndex"] },
                      [
                        {
                          key: "$$this.key",
                          value: { $sum: [{ $arrayElemAt: ["$$value.value", "$$existingIndex"] }, "$$this.value"] }
                        }
                      ],
                      { $slice: ["$$value", { $add: ["$$existingIndex", 1] }, { $size: "$$value" }] }
                    ]
                  },
                  else: { $concatArrays: ["$$value", ["$$this"]] }
                }
              }
            }
          }
        }
      }
    }
  }
])

本方案兼容MongoDB 3.4及以上版本,全部使用原生聚合算子实现,不需要额外开启服务端JS执行权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:54:05