MongoDB聚合查询:按多字段分组生成指定格式统计结果
MongoDB聚合查询:合并多状态统计结果
样本集合数据
{ "name": "test", "data": { "statusOne": "enabled", "statusTwo": "active" } } { "name": "test", "data": { "statusOne": "disabled", "statusTwo": "active" } } { "name": "another-test", "data": { "statusOne": "disabled", "statusTwo": "active" } }
期望输出格式
需按name分组,同时统计statusOne和statusTwo各值的出现次数,最终合并到data字段中:
[ { "name": "test", "data": [ { "status": "active", "count": 2 }, { "status": "disabled", "count": 1 }, { "status": "enabled", "count": 1 } ] }, { "name": "another-test", "data": [ { "status": "active", "count": 1 }, { "status": "disabled", "count": 1 } ] } ]
我的尝试代码(未达到预期)
[ { $group: { _id: { appName: "$name", cs: "$data.statusOne", ps: "$data.statusTwo", }, total: { $sum: 1, }, }, }, { $group: { _id: "$_id.appName", total: { $sum: "$total" }, ps: { $addToSet: { name: "$_id.ps", count: "$total", }, }, cs: { $addToSet: { name: "$_id.cs", count: "$total", }, }, }, }, { $project: { _id: 0, appName: "$_id", items: { $concatArrays: ["$ps", "$cs"], }, }, }, ]
正确聚合查询方案
核心思路是先把每个文档中的两个status字段拆分为独立条目,再统一统计:
[ // 1. 将每个文档的statusOne和statusTwo转为数组形式,方便后续拆分 { $addFields: { statusList: [ "$data.statusOne", "$data.statusTwo" ] } }, // 2. 拆分数组,每个status值成为单独文档 { $unwind: "$statusList" }, // 3. 按name和status值分组,统计每个组合的出现次数 { $group: { _id: { name: "$name", status: "$statusList" }, count: { $sum: 1 } } }, // 4. 按name重新分组,将统计结果整理到data数组中 { $group: { _id: "$_id.name", data: { $push: { status: "$_id.status", count: "$count" } } } }, // 5. 调整输出字段,去掉_id,将_id转为name { $project: { _id: 0, name: "$_id", data: 1 } } ]
步骤说明
- $addFields:给每个文档添加
statusList数组,包含statusOne和statusTwo的取值,把两个状态字段统一成数组结构。 - $unwind:将数组拆分成多个文档,每个文档对应一个状态值,实现对所有状态值的统一统计。
- $group(第一次):按
name和status值分组,计算每个状态在对应name下的出现次数。 - $group(第二次):按
name分组,用$push将同一name下的所有统计结果整理到data数组。 - $project:调整输出字段名,移除系统生成的
_id,将分组用的_id转为name字段,匹配期望输出格式。
内容的提问来源于stack exchange,提问作者user3518008
相关产品推荐
相关产品推荐

