MongoDB聚合多文档统计finish字段并返回原文档数组的方法
MongoDB聚合实现方案
这个需求完全可实现,你已经掌握了条件计数的写法,只需要通过多分支聚合同时完成文档收集即可,不需要多次查询。
核心实现逻辑
使用$facet阶段在单次聚合里跑两个独立的处理分支:
- 第一个分支复用你已经写好的条件判断逻辑,统计
finish=true和finish=false的文档数量 - 第二个分支直接收集所有经过前置筛选的原文档,存入
results数组
最后再调整输出结构,匹配你要的格式即可。
可直接运行的聚合代码
// 替换成你实际的集合名称 db.your_collection.aggregate([ // 如果需要先筛选指定范围的文档(比如按创建时间、所属用户过滤),在这里加$match阶段即可 // { $match: { create_time: { $gte: ISODate("2024-01-01T00:00:00Z") } } }, { $facet: { count_stage: [ { $group: { _id: null, finish: { $sum: { $cond: [{ $eq: ["$finish", true] }, 1, 0] } }, non_finish: { $sum: { $cond: [{ $eq: ["$finish", false] }, 1, 0] } } } } ], collect_docs: [ // 保留原文档完整结构,如果只需要返回部分字段,可以替换成$project指定字段 { $replaceRoot: { newRoot: "$$ROOT" } } ] } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: ["$count_stage", 0] }, { results: "$collect_docs" } ] } } }, { $project: { _id: 0 } } ])
注意事项
- 如果要筛选统计范围,不要把
$match写在$facet内部的分支里,写在$facet前面可以让两个分支共用筛选条件,性能更好。 - MongoDB单条聚合结果文档最大不能超过16MB,如果你的文档总量很大,把全量文档塞进
results数组会触发大小上限报错,这种场景建议拆分查询:一次查统计值,一次分页查文档列表,不要强行返回全量文档数组。 - 如果不需要返回文档的全部字段,可以在
collect_docs分支里加$project阶段指定需要返回的字段,减少数据传输量。
内容的提问来源于stack exchange,提问作者initprism
相关产品推荐
相关产品推荐

