MongoDB聚合合并分类与子分类分组计数单次查询实现
MongoDB 单次聚合实现分类与子分类联合统计
问题说明
开展分类、子分类维度数据统计时,当前使用两套独立MongoDB聚合管道分别执行查询:
- 分类统计管道:仅返回分类名称、分类总计数
返回结构:[ { "$match": { "category": { "$in": ["list of my categories"] } } }, { "$group": { "category": "$category", "count": { "$sum": 1 } } } ]{category: 分类名称, count: 分类总计数} - 子分类统计管道:返回分类下各子分类的计数键值对
[ { "$match": { "category": { "$in": ["list of my categories"] } } }, { "$group": { "_id": { subCategory: "$subCategory", category: "$category" }, "count": { "$sum": 1 } } }, { "$group": { "_id": "$_id.category", "counts": { "$push": { "k": "$_id.subCategory", "v": "$count" }, }, "count":{ $sum: "$counts" } } }, { "$project": { "counts": { "$arrayToObject": "$counts" }, } } ]
需要将两套独立管道合并为单次聚合调用,直接返回包含分类名、分类总计数、下属子分类计数字典的结果。
实现方案
原有子分类管道中$sum: "$counts"为错误写法,分组阶段$sum无法直接对数组类型字段求和,修正后合并的完整聚合管道如下:
[ // 筛选目标分类范围,逻辑和原有管道保持一致 { $match: { category: { $in: ["list of my categories"] // 替换为实际分类列表 } } }, // 先按「分类+子分类」双维度分组,统计每个子分类下的文档数 { $group: { _id: { category: "$category", subCategory: "$subCategory" }, subCount: { $sum: 1 } } }, // 再按分类维度聚合,同时计算分类总计数、收集所有子分类计数 { $group: { _id: "$_id.category", count: { $sum: "$subCount" }, subCountsArr: { $push: { k: "$_id.subCategory", v: "$subCount" } } } }, // 调整输出格式,匹配要求的返回结构 { $project: { _id: 0, category: "$_id", count: 1, subCategoryCounts: { $arrayToObject: "$subCountsArr" } } } ]
返回结果示例
[ { "category": "家居用品", "count": 132, "subCategoryCounts": { "厨具": 48, "床品": 52, "收纳": 32 } }, { "category": "食品饮料", "count": 217, "subCategoryCounts": { "零食": 92, "饮品": 78, "生鲜": 47 } } ]
该管道仅需对集合做一次匹配扫描,相比两次独立查询减少了重复遍历开销,统计结果和两次查询完全一致。
内容的提问来源于stack exchange,提问作者EMT
相关产品推荐
相关产品推荐

