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

如何使用MongoDB聚合管道实现双层数据分区求和?

按key和subkey双层分区对amount求和的最佳实现(除$setWindowFields外)

我有一份样本数据,需要按key和subkey两个字段进行双层分区,并对分组后的amount字段求和。

样本数据

[
  {
    "key": "1",
    "subkey": "1_1",
    "amount": 1
  },
  {
    "key": "1",
    "subkey": "1_1",
    "amount": 2
  },
  {
    "key": "1",
    "subkey": "1_2",
    "amount": 5
  },
  {
    "key": "2",
    "subkey": "2_1",
    "amount": 3
  },
  {
    "key": "2",
    "subkey": "2_2",
    "amount": 4
  }
]

当前使用的聚合管道(subkey层级分组效果不佳)

db.collection.aggregate({
  "$setWindowFields": {
    "partitionBy": "$key",
    "sortBy": {
      "subkey": 1
    },
    "output": {
      "total": {
        "$sum": "$amount",
        "window": {
          "documents": [
            "unbounded",
            "current"
          ]
        }
      }
    }
  }
})

预期输出

key | subkey | total
 1  | 1_1    | 3
 1  | 1_2    | 5
 2  | 2_1    | 3
 2  | 2_2    | 4

最佳实现方式:使用$group复合分组

直接通过$group阶段以key和subkey的组合作为分组键,是实现该需求最高效、最直接的方式,完全匹配预期输出:

db.collection.aggregate([
  {
    $group: {
      _id: {
        key: "$key",
        subkey: "$subkey"
      },
      total: { $sum: "$amount" }
    }
  },
  {
    $project: {
      _id: 0,
      key: "$_id.key",
      subkey: "$_id.subkey",
      total: 1
    }
  }
])

逻辑说明

  1. $group阶段:将_id设置为包含key和subkey的复合对象,以此作为双层分区的依据,同时用$sum计算每组的amount总和。
  2. $project阶段:将分组生成的_id对象拆解为独立的key和subkey字段,移除默认的_id字段,让输出结构与预期一致。

这种方式相比$setWindowFields更适合此类场景:$setWindowFields多用于滑动窗口、累计求和等复杂窗口计算,而单纯的分组求和用$group性能更优,逻辑也更清晰。

内容的提问来源于stack exchange,提问作者Joseph D.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:06:02