MongoDB多字段分组统计状态总数问题求助
MongoDB分组统计解决方案
核心思路
无需两次$group,一次分组即可完成所有统计需求。通过$ifNull判断status字段是否存在,结合$cond条件分支分别累加各类状态的计数,最后直接计算总计。
完整聚合管道
db.collection.aggregate([ // 可选:显式排除timestamp字段,减少后续处理数据量,$group会自动忽略未引用字段,也可跳过此阶段 { $project: { timestamp: 0, associatedId: 1, transactionId: 1, status: 1 } }, { $group: { _id: { associatedId: "$associatedId", transactionId: "$transactionId" }, RESOLVED_TOTAL: { $sum: { $cond: [{ $eq: ["$status", "RESOLVED"] }, 1, 0] } }, NOT_RESOLVED_TOTAL: { $sum: { $cond: [{ $eq: ["$status", "NOT_RESOLVED"] }, 1, 0] } }, ABSENT_TOTAL: { $sum: { $cond: [{ $ifNull: ["$status", false] }, 0, 1] } } } }, { $project: { _id: 0, associatedId: "$_id.associatedId", transactionId: "$_id.transactionId", RESOLVED_TOTAL: 1, NOT_RESOLVED_TOTAL: 1, ABSENT_TOTAL: 1, GRAND_TOTAL: { $sum: ["$RESOLVED_TOTAL", "$NOT_RESOLVED_TOTAL", "$ABSENT_TOTAL"] } } } ])
阶段解释
- $project阶段(可选):仅保留需要的字段,排除
timestamp,降低后续阶段的数据处理压力。 - $group阶段:
- 以
associatedId和transactionId的组合作为分组键 RESOLVED_TOTAL:统计status为RESOLVED的文档数量NOT_RESOLVED_TOTAL:统计status为NOT_RESOLVED的文档数量ABSENT_TOTAL:通过$ifNull判断status是否缺失,缺失则累加计数
- 以
- $project阶段:
- 展开分组键中的字段为顶层字段,优化输出格式
- 计算
GRAND_TOTAL,即三类状态计数的总和
兼容初始思路的替代方案
如果坚持先标记缺失status的文档为ABSENT,可调整管道如下,同样一次$group完成统计:
db.collection.aggregate([ { $project: { timestamp: 0, associatedId: 1, transactionId: 1, status: { $ifNull: ["$status", "ABSENT"] } } }, { $group: { _id: { associatedId: "$associatedId", transactionId: "$transactionId" }, RESOLVED_TOTAL: { $sum: { $cond: [{ $eq: ["$status", "RESOLVED"] }, 1, 0] } }, NOT_RESOLVED_TOTAL: { $sum: { $cond: [{ $eq: ["$status", "NOT_RESOLVED"] }, 1, 0] } }, ABSENT_TOTAL: { $sum: { $cond: [{ $eq: ["$status", "ABSENT"] }, 1, 0] } }, GRAND_TOTAL: { $sum: 1 } } }, { $project: { _id: 0, associatedId: "$_id.associatedId", transactionId: "$_id.transactionId", RESOLVED_TOTAL: 1, NOT_RESOLVED_TOTAL: 1, ABSENT_TOTAL: 1, GRAND_TOTAL: 1 } } ])
此方案先将缺失status的文档标记为ABSENT,再直接统计三类状态的数量,GRAND_TOTAL通过$sum:1直接统计分组内总文档数,效率更高。
内容的提问来源于stack exchange,提问作者cmodha
相关产品推荐
相关产品推荐

