MongoDB中按指定字段对对象数组分组统计数量的求助
MongoDB按多字段分组统计药品数据解决方案
原始数据
[ { medicationDetails: { category: 'Asthma', subCategory: '', providedBy: 'Doctor' } }, { medicationDetails: { category: 'Diabetes', subCategory: 'Oral', providedBy: 'Nurse' } }, { medicationDetails: { category: 'Asthma', subCategory: '', providedBy: 'Doctor' } }, { medicationDetails: { category: 'Diabetes', subCategory: 'Insulin', providedBy: 'Doctor' } } ]
需求说明
需要按category、subCategory和providedBy分组,统计每个分组下医生和护士提供的数量,最终输出如下格式:
[ { medicationDetails: [ { name: 'Asthma', providedByDoctorCount: 2, providedByNurseCount: 0 }, { name: 'Oral', providedByDoctorCount: 0, providedByNurseCount: 1 }, { name: 'Insulin', providedByDoctorCount: 1, providedByNurseCount: 0 } ] } ]
解决方案
通过MongoDB聚合管道可以实现需求,核心是先统一分组名称,再分层统计,最后整理成目标格式:
db.collection.aggregate([ // 统一提取分组名称:subCategory为空时用category,否则用subCategory { $project: { name: { $cond: [ { $eq: [ "$medicationDetails.subCategory", "" ] }, "$medicationDetails.category", "$medicationDetails.subCategory" ] }, providedBy: "$medicationDetails.providedBy" } }, // 按名称和提供者分组,统计基础数量 { $group: { _id: { name: "$name", provider: "$providedBy" }, count: { $sum: 1 } } }, // 按名称合并,拆分医生/护士的统计数到对应字段 { $group: { _id: "$_id.name", providedByDoctorCount: { $sum: { $cond: [ { $eq: [ "$_id.provider", "Doctor" ] }, "$count", 0 ] } }, providedByNurseCount: { $sum: { $cond: [ { $eq: [ "$_id.provider", "Nurse" ] }, "$count", 0 ] } } } }, // 整理字段:把_id转成name,移除原始_id { $project: { _id: 0, name: "$_id", providedByDoctorCount: 1, providedByNurseCount: 1 } }, // 将所有统计项合并到medicationDetails数组 { $group: { _id: null, medicationDetails: { $push: "$$ROOT" } } }, // 移除多余的_id字段 { $project: { _id: 0, medicationDetails: 1 } } ])
步骤拆解
- $project阶段:解决subCategory为空的问题,统一分组的
name字段值。 - 第一次$group阶段:先按「名称+提供者」的组合统计基础数量,为后续拆分做准备。
- 第二次$group阶段:按名称合并,用条件判断把医生、护士的统计数分别存入对应字段。
- 字段整理阶段:调整字段结构,让输出更贴合需求格式。
- 最终合并阶段:把所有统计结果打包成目标数组,移除无关字段。
内容的提问来源于stack exchange,提问作者Code The World
相关产品推荐
相关产品推荐

