如何将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
相关产品推荐
相关产品推荐

