如何合并MongoDB中按companyRegNo分组的三个聚合计数查询?
解决MongoDB按公司分组合并多类型统计的问题
你的问题出在**$facet子管道未按companyRegNo分组**,而是做了全局汇总(_id: null),所以得到的是全公司的总数,而非各公司的拆分统计。下面提供两种解决方案:
方案一:单分组+条件计数(推荐,性能更优)
直接通过一次$group按公司分组,结合$sum和$cond条件判断,一次性统计每个公司的三类指标:
db.employeeActions.aggregate([ // 按companyRegNo分组,统计各类型数量 { $group: { _id: "$companyRegNo", Applications: { $sum: { $cond: [{ $eq: ["$actionType", "application"] }, 1, 0] } }, Reviews: { $sum: { $cond: [{ $eq: ["$actionType", "review"] }, 1, 0] } }, Offers: { $sum: { $cond: [{ $eq: ["$actionType", "offer"] }, 1, 0] } } } }, // 重命名字段,匹配你需要的输出格式 { $project: { CompanyRegNo: "$_id", _id: 0, Applications: 1, Reviews: 1, Offers: 1 } } ])
说明
$cond判断当前文档的actionType是否匹配目标类型,匹配则加1,否则加0- 一次分组即可完成所有统计,避免多次遍历集合,性能更高效
方案二:修正$facet逻辑(保留原查询思路)
如果你坚持用$facet合并三个查询,需要让每个子管道先按companyRegNo分组,再合并结果:
db.employeeActions.aggregate([ // 分三个子管道分别统计各公司的三类指标 { $facet: { applications: [ { $match: { actionType: "application" } }, { $group: { _id: "$companyRegNo", Applications: { $sum: 1 } } } ], reviews: [ { $match: { actionType: "review" } }, { $group: { _id: "$companyRegNo", Reviews: { $sum: 1 } } } ], offers: [ { $match: { actionType: "offer" } }, { $group: { _id: "$companyRegNo", Offers: { $sum: 1 } } } ] } }, // 将三个统计数组合并为一个数组 { $project: { allData: { $concatArrays: ["$applications", "$reviews", "$offers"] } } }, // 展开合并后的数组 { $unwind: "$allData" }, // 按companyRegNo重新分组,合并各类型统计值 { $group: { _id: "$allData._id", Applications: { $max: "$allData.Applications" }, Reviews: { $max: "$allData.Reviews" }, Offers: { $max: "$allData.Offers" } } }, // 把null值转为0,重命名字段 { $project: { CompanyRegNo: "$_id", _id: 0, Applications: { $ifNull: ["$Applications", 0] }, Reviews: { $ifNull: ["$Reviews", 0] }, Offers: { $ifNull: ["$Offers", 0] } } } ])
说明
- 每个
$facet子管道先筛选对应类型的数据,再按companyRegNo分组得到该公司的类型计数 - 通过
$concatArrays和$unwind合并三个结果集,再重新分组合并字段 $ifNull确保没有对应类型数据的公司显示0而非null
错误原因分析
你之前的$facet尝试大概率是在子管道中用了_id: null做全局分组,比如:
// 错误示例 db.employeeActions.aggregate([ { $facet: { applications: [ { $match: { actionType: "application" } }, { $group: { _id: null, count: { $sum: 1 } } } // 全局汇总,而非按公司分组 ] } } ])
这种写法会把所有匹配类型的数据汇总成一个总数,自然无法得到按公司拆分的统计结果。
内容的提问来源于stack exchange,提问作者cms
相关产品推荐
相关产品推荐

