NodeJS+MongoDB多属性聚合查询:按分类统计子品类状态数量
解决MongoDB按分类和子分类统计商品状态的聚合查询问题
正确的聚合查询实现
直接使用MongoDB的聚合管道可以一步完成需求,以下是完整的Node.js代码:
const itemsCount = await Item.aggregate([ // 按分类和子分类分组,统计各状态商品数 { $group: { _id: { category: "$category", subCategory: "$subCategory" }, inStock: { $sum: { $cond: [{ $eq: ["$status", "inStock"] }, 1, 0] } }, outOfStock: { $sum: { $cond: [{ $eq: ["$status", "outOfStock"] }, 1, 0] } }, pending: { $sum: { $cond: [{ $eq: ["$status", "pending"] }, 1, 0] } } } }, // 计算该子分类下的总商品数 { $addFields: { "items in total": { $add: ["$inStock", "$outOfStock", "$pending"] } } }, // 调整输出字段格式,符合需求 { $project: { _id: 0, category: "$_id.category", subcategory: "$_id.subCategory", inStock: 1, outOfStock: 1, pending: 1, "items in total": 1 } }, // 可选:过滤出仅在Category集合中存在的合法分类组合 { $lookup: { from: "categories", // 替换为你的Category集合实际名称 localField: "category", foreignField: "category", as: "categoryData" } }, { $unwind: "$categoryData" }, { $match: { $expr: { $in: ["$subcategory", "$categoryData.subCategory"] } } }, { $project: { categoryData: 0 } } ]);
关键阶段解释
- $group:以
category和subCategory的组合作为分组依据,使用$cond判断每个商品的状态,对应状态计数加1,实现各状态的数量统计。 - $addFields:通过
$add将三个状态的数量相加,得到该子分类的总商品数。 - $project:重新整理输出字段,移除默认的
_id,将分组键中的字段提取为独立字段,匹配需求格式。 - 可选的分类验证:如果你的Item集合中可能存在Category未定义的分类/子分类,通过
$lookup关联Category集合,再用$in过滤掉非法组合。
原代码的问题分析
- 字段名不匹配:原代码中使用
categoryName、subCategories,但你的集合实际字段是category、subCategory,导致匹配逻辑失效。 - $match语法错误:
$match接收的是单个查询条件对象,不是数组,直接传入toMatch数组不符合MongoDB语法。 - 分组逻辑错误:原代码按
status分组,只能得到全局各状态的总数量,无法按分类和子分类拆分统计。 - 缺失总数计算:原代码未实现总商品数的统计逻辑。
内容的提问来源于stack exchange,提问作者enNa
相关产品推荐
相关产品推荐

