You need to enable JavaScript to run this app. 如何对嵌套数组内指定分组的items子数组求和并更新total字段
优惠活动
大模型
产品
解决方案
定价
更多

如何对嵌套数组内指定分组的items子数组求和并更新total字段

实现方案

以下两种方案均可实现需求,可根据你使用的MongoDB版本选择:

方案1:MongoDB 4.2+ 聚合更新(推荐)

该版本支持直接在update操作中传入聚合管道,无需额外查询,一步完成更新,不需要使用$unwind操作:

// 示例为更新group_id为A的分组total字段
db.collection.updateOne(
  // 匹配包含目标分组的文档,可补充其他文档筛选规则
  { "groups.group_id": "A" },
  [
    {
      $set: {
        groups: {
          $map: {
            input: "$groups",
            as: "group",
            in: {
              $cond: {
                if: { $eq: ["$$group.group_id", "A"] },
                // 仅修改目标分组,其余分组保持不变
                then: {
                  $mergeObjects: [
                    "$$group",
                    { total: { $sum: "$$group.items.val" } }
                  ]
                },
                else: "$$group"
              }
            }
          }
        }
      }
    }
  ]
)

逻辑说明:

  • 外层$match先过滤出存在目标分组的文档,减少无效扫描
  • $map遍历groups数组,仅对指定group_id的元素做修改
  • $sum直接对目标分组下的items.val数组求和,无需拆分数组
  • $mergeObjects保留分组原有全部字段,仅覆盖total值,不会丢失数据

方案2:含$unwind的兼容方案(支持MongoDB 4.2以下版本)

如果你需要使用$unwind操作,或是MongoDB版本较低不支持聚合更新,可先查询计算总和再执行更新:

// 第一步:查询计算目标分组的val总和
const aggResult = db.collection.aggregate([
  { $match: { "groups.group_id": "A" } },
  // 拆分groups数组
  { $unwind: "$groups" },
  // 仅保留目标分组的记录,不处理其他分组
  { $match: { "groups.group_id": "A" } },
  {
    $project: {
      total: { $sum: "$groups.items.val" },
      _id: 1
    }
  }
]).toArray()

// 第二步:执行更新
if (aggResult.length > 0) {
  const { _id, total } = aggResult[0]
  db.collection.updateOne(
    { _id: _id, "groups.group_id": "A" },
    { $set: { "groups.$.total": total } }
  )
}

提示:将上述代码中的A替换为你实际要操作的group_id,db.collection替换为你的真实集合名称即可运行。如果需要同时更新多个符合条件的文档,将updateOne替换为updateMany即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 22:45:10