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

如何用MongoDB聚合合并同key对象数组并计算总值

MongoDB按日期分组并合并channels同key值求和的聚合方案

原始数据

[
  {
    "_id": ObjectId("65aa4921c767f95a70b8867f"),
    "creator": "Henry",
    "date": "2023-12-22",
    "channels": [
      {
        "key": "HTV",
        "value": 1
      }
    ]
  },
  {
    "_id": ObjectId("65aa4921c767f95a70b8867f"),
    "creator": "Max",
    "date": "2023-12-23",
    "channels": [
      {
        "key": "VTC",
        "value": 1
      }
    ]
  },
  {
    "_id": ObjectId("65aa4921c767f95a70b88689"),
    "creator": "John",
    "date": "2023-12-23",
    "channels": [
      {
        "key": "VTC",
        "value": 2
      },
      {
        "key": "HTV",
        "value": 1
      }
    ]
  }
]

需求说明

  • 按date字段分组
  • 合并channels数组中key相同的元素,计算对应value的总和
  • 统计每组所有value的总和(即Total字段)

现有代码片段

model.aggregate([
  {
    $group: {
      _id: {
        date: '$date'
      },
      Total: { $sum: { $sum: '$channels.value' } }
    }
  }
])

期望输出结果

[
  {
    "date": "2023-12-22",
    "channels": [
      {
        "key": "HTV",
        "value": 1
      }
    ],
    "Total": 1
  },
  {
    "date": "2023-12-23",
    "channels": [
      {
        "key": "VTC",
        "value": 3   // 1 + 2
      },
      {
        "key": "HTV",
        "value": 1
      }
    ],
    "Total": 4
  }
]

完整聚合解决方案

要实现需求,需要在现有代码基础上补充$unwind和多轮$group操作,完整的聚合管道如下:

model.aggregate([
  // 1. 将每个文档的channels数组拆分为单个文档,便于按key分组计算
  { $unwind: "$channels" },
  // 2. 先按date和channels.key分组,计算每个key在对应日期下的value总和,同时累加总value
  {
    $group: {
      _id: {
        date: "$date",
        key: "$channels.key"
      },
      keyTotal: { $sum: "$channels.value" },
      totalSum: { $sum: "$channels.value" }
    }
  },
  // 3. 再按date分组,将每个key的结果组装成channels数组,同时计算该日期的总Total
  {
    $group: {
      _id: "$_id.date",
      channels: {
        $push: {
          key: "$_id.key",
          value: "$keyTotal"
        }
      },
      Total: { $sum: "$totalSum" }
    }
  },
  // 4. 调整输出格式,将_id改为date字段,保持结构与期望一致
  {
    $project: {
      _id: 0,
      date: "$_id",
      channels: 1,
      Total: 1
    }
  }
])

步骤解释

  1. $unwind:把每个文档中的channels数组拆分成独立的文档,每个文档包含一个channels对象,这样就能针对每个key单独进行求和操作。
  2. 第一次$group:以date和channels.key为组合分组键,计算每个key在对应日期下的value总和(keyTotal),同时累加该分组的总value(totalSum)。
  3. 第二次$group:以date为分组键,将同一日期下的所有key结果通过$push组装成channels数组,同时把所有totalSum相加得到该日期的总Total。
  4. $project:重新格式化输出文档,将_id替换为date字段,移除不必要的_id,确保输出结构与期望一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:35:31