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

MongoDB聚合:能否在$sum操作符内使用$match实现属性求和?

问题解答

首先明确:$sum聚合函数里不能使用$match操作符,$match是聚合管道的独立阶段,只能作为管道中的一个步骤,不能嵌套在$sum这类表达式里使用。

针对你的需求——筛选FIGHT_PROP_CRITICAL和FIGHT_PROP_CRITICAL_HURT属性,计算(2*FIGHT_PROP_CRITICAL) + FIGHT_PROP_CRITICAL_HURT的结果并排序,下面是正确的实现方式:

假设你的原始数据结构

假设每个文档包含一个stats数组,结构如下:

{
  "id": 1,
  "stats": [
    {"propType": "FIGHT_PROP_CRITICAL", "statValue": 15},
    {"propType": "FIGHT_PROP_CRITICAL_HURT", "statValue": 60},
    {"propType": "FIGHT_PROP_ATTACK", "statValue": 100}
  ]
}

正确的聚合管道

db.collection.aggregate([
  // 提取目标属性值,处理缺失情况(缺失则设为0)
  {
    $addFields: {
      critical: {
        $ifNull: [
          {$getField: {
            field: "statValue",
            input: {$arrayElemAt: [{$filter: {
              input: "$stats",
              cond: {$eq: ["$$this.propType", "FIGHT_PROP_CRITICAL"]}
            }}, 0]}
          }},
          0
        ]
      },
      criticalHurt: {
        $ifNull: [
          {$getField: {
            field: "statValue",
            input: {$arrayElemAt: [{$filter: {
              input: "$stats",
              cond: {$eq: ["$$this.propType", "FIGHT_PROP_CRITICAL_HURT"]}
            }}, 0]}
          }},
          0
        ]
      }
    }
  },
  // 计算目标值
  {
    $addFields: {
      totalCriticalValue: {$add: [{$multiply: [2, "$critical"]}, "$criticalHurt"]}
    }
  },
  // 可选:过滤掉两个属性都为0的无效文档
  {
    $match: {
      $or: [
        {"critical": {$gt: 0}},
        {"criticalHurt": {$gt: 0}}
      ]
    }
  },
  // 按计算值排序(-1为降序,1为升序)
  {
    $sort: {totalCriticalValue: -1}
  },
  // 可选:只保留需要的字段
  {
    $project: {
      _id: 0,
      id: 1,
      totalCriticalValue: 1,
      critical: 1,
      criticalHurt: 1
    }
  }
])

代码说明

  1. $addFields阶段:用$filter从stats数组中筛选目标属性,$arrayElemAt取第一个匹配项,$getField提取对应的statValue,$ifNull处理属性缺失的情况,避免计算报错。
  2. 计算目标值:通过$multiply计算2倍暴击值,再用$add叠加暴击伤害,得到最终的totalCriticalValue。
  3. 可选$match:过滤掉两个属性都不存在的文档,排除无效数据。
  4. $sort阶段:按计算出的结果排序,满足你的排序需求。

输入输出示例

输入文档

[
  {"id": 1, "stats": [{"propType": "FIGHT_PROP_CRITICAL", "statValue": 15}, {"propType": "FIGHT_PROP_CRITICAL_HURT", "statValue": 60}]},
  {"id": 2, "stats": [{"propType": "FIGHT_PROP_CRITICAL", "statValue": 20}, {"propType": "FIGHT_PROP_CRITICAL_HURT", "statValue": 50}]},
  {"id": 3, "stats": [{"propType": "FIGHT_PROP_ATTACK", "statValue": 200}]}
]

输出结果

[
  {"id": 2, "critical": 20, "criticalHurt": 50, "totalCriticalValue": 90},
  {"id": 1, "critical": 15, "criticalHurt": 60, "totalCriticalValue": 90}
  // 开启可选$match后,id=3的文档会被过滤
]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:45:48