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

MongoDB中子文档字段求和的聚合查询实现

MongoDB多文档按货币类型求和聚合方案

方案一:使用$unwind(高效直观)

这是最常用的实现方式,通过拆解price数组元素,按货币类型分组求和后重组结果:

db.products.aggregate([
  // 拆解每个文档的price数组,每个数组元素成为独立文档
  { $unwind: "$price" },
  // 按currency分组,累加对应amount
  {
    $group: {
      _id: "$price.currency",
      totalAmount: { $sum: "$price.amount" }
    }
  },
  // 将分组结果重组为{grossIncome: [...]}结构
  {
    $group: {
      _id: null,
      grossIncome: {
        $push: {
          amount: "$totalAmount",
          currency: "$_id"
        }
      }
    }
  },
  // 移除_id字段,只保留目标结果
  { $project: { _id: 0 } }
])

方案二:不使用$unwind(适用于特殊场景)

如果需要避免使用$unwind,可以通过合并所有price数组后,利用$reduce和数组转换操作实现分组求和:

db.products.aggregate([
  // 收集所有文档的price数组,合并为一个扁平化数组
  {
    $group: {
      _id: null,
      allPrices: { $push: "$price" }
    }
  },
  {
    $project: {
      allPrices: { $concatArrays: "$allPrices" },
      _id: 0
    }
  },
  // 按货币类型分组求和,转换为键值对对象
  {
    $project: {
      grossIncome: {
        $arrayToObject: {
          $reduce: {
            input: "$allPrices",
            initialValue: [],
            in: {
              $let: {
                vars: {
                  current: "$$this",
                  existingIndex: { $indexOfArray: ["$$value.currency", "$$this.currency"] }
                },
                in: {
                  $cond: {
                    if: { $ne: ["$$existingIndex", -1] },
                    then: {
                      $map: {
                        input: "$$value",
                        as: "item",
                        in: {
                          $cond: {
                            if: { $eq: ["$$item.currency", "$$current.currency"] },
                            then: { currency: "$$item.currency", amount: { $add: ["$$item.amount", "$$current.amount"] } },
                            else: "$$item"
                          }
                        }
                      }
                    },
                    else: { $concatArrays: ["$$value", ["$$current"]] }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  // 将键值对对象转换为期望的数组格式
  {
    $project: {
      grossIncome: { $objectToArray: "$grossIncome" }
    }
  },
  {
    $project: {
      grossIncome: {
        $map: {
          input: "$grossIncome",
          as: "item",
          in: { currency: "$$item.k", amount: "$$item.v.amount" }
        }
      }
    }
  }
])

结果验证

两种方案执行后都会返回符合需求的结果:

{
  "grossIncome": [
    { "amount": 430, "currency": "USD" },
    { "amount": 70, "currency": "EUR" }
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:10:28