如何通过MongoDB聚合实现按类型分组并统计属性区间?
单次MongoDB聚合实现按Type分组并统计Properties区间数量
示例数据
db.collection.insertMany([ { type: "A", properties: [] }, { type: "A", properties: ["x"] }, { type: "A", properties: ["x", "y"] }, { type: "A", properties: ["x", "y", "z"] }, { type: "A", properties: ["x", "y", "z", "w"] }, { type: "B", properties: [] }, { type: "B", properties: ["a"] }, { type: "B", properties: ["a", "b"] }, { type: "B", properties: ["a", "b", "c"] } ]);
正确聚合管道
db.collection.aggregate([ // 计算每个文档的properties数组长度 { $addFields: { propCount: { $size: "$properties" } } }, // 按type分组,统计各区间数量 { $group: { _id: "$type", count_0: { $sum: { $cond: [{ $eq: ["$propCount", 0] }, 1, 0] } }, count_1: { $sum: { $cond: [{ $eq: ["$propCount", 1] }, 1, 0] } }, count_2: { $sum: { $cond: [{ $eq: ["$propCount", 2] }, 1, 0] } }, count_3_plus: { $sum: { $cond: [{ $gte: ["$propCount", 3] }, 1, 0] } } } }, // 可选:调整输出字段名称,优化可读性 { $project: { type: "$_id", _id: 0, "0个": "$count_0", "1个": "$count_1", "2个": "$count_2", "3个及以上": "$count_3_plus" } } ]);
期望输出结果
[ { "type": "A", "0个": 1, "1个": 1, "2个": 1, "3个及以上": 2 }, { "type": "B", "0个": 1, "1个": 1, "2个": 1, "3个及以上": 1 } ]
逻辑说明
- $addFields阶段:为每个文档生成
propCount字段,存储properties数组的长度,避免后续重复计算,提升效率。 - $group阶段:以
type为分组键,通过$cond条件判断每个文档的propCount属于哪个区间,符合条件则用$sum累加计数。 - $project阶段:可选步骤,将分组结果的字段名调整为更直观的中文名称,若不需要可直接省略。
常见错误规避
- 不要在
$group的$cond中重复调用$size计算数组长度,多次计算会增加不必要的性能开销。 - 避免提前用
$match过滤文档,否则会导致统计数据不全,必须确保所有文档都参与分组统计。
内容的提问来源于stack exchange,提问作者GaddBox
相关产品推荐
相关产品推荐

