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

如何将MongoDB聚合查询中的$sum替换为count以测试性能?

MongoDB聚合查询:替换$sum为计数逻辑的实现

问题

我有如下MongoDB聚合查询,希望使用计数(count)逻辑替代$sum来测试性能。注:实际场景中$addFields内的条件不同,仅需替换$sum相关的计数逻辑。

集合示例

[
  {
    "rate": 500,
    "orderDate": 20230101,
    "username": "Brad"
  },
  {
    "rate": 20,
    "orderDate": 20230101,
    "username": "Lewis"
  },
  {
    "rate": 200,
    "orderDate": 20230101,
    "username": "Brad"
  }
]

原聚合查询

db.collection.aggregate([
  {
    $match: {
      orderDate: 20230101
    }
  },
  {
    $addFields: {
      validOrder: 1
    }
  },
  {
    $group: {
      _id: "$username",
      approvedOrder: {
        $sum: "$validOrder"
      }
    }
  }
])

预期输出

[
  {
    "_id": "Lewis",
    "approvedOrder": 1
  },
  {
    "_id": "Brad",
    "approvedOrder": 2
  }
]

解决方案

MongoDB的$group阶段没有专门的$count累加器,但可以通过以下两种方式实现等价的计数效果:

方式一:直接替换为$sum: 1

原查询中validOrder被赋值为1,每个匹配文档都会贡献1到总和,因此用$sum: 1可以直接得到分组内的文档数量,与原查询结果完全一致:

db.collection.aggregate([
  {
    $match: {
      orderDate: 20230101
    }
  },
  {
    $addFields: {
      validOrder: 1
    }
  },
  {
    $group: {
      _id: "$username",
      approvedOrder: {
        $sum: 1 // 替换原$sum: "$validOrder"
      }
    }
  }
])

方式二:过滤后再计数(贴合count逻辑)

如果实际场景中validOrder是条件判断生成的1或0(比如符合条件为1,否则为0),可以先过滤掉无效文档,再统计分组数量,更符合“计数”的直观逻辑:

db.collection.aggregate([
  {
    $match: {
      orderDate: 20230101
    }
  },
  {
    $addFields: {
      validOrder: 1 // 实际场景为条件表达式,例如$cond判断
    }
  },
  {
    $match: {
      validOrder: 1 // 仅保留有效文档
    }
  },
  {
    $group: {
      _id: "$username",
      approvedOrder: {
        $sum: 1
      }
    }
  }
])

说明

MongoDB的$count是一个独立的聚合阶段,仅用于统计整个管道的文档总数,无法在$group阶段作为累加器使用。分组统计时,$sum: 1是最高效的等价实现方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 17:18:15