MongoDB聚合查询优化:按make分组后再按color分组
我来帮你调整这条聚合查询,刚好能解决你说的颜色字段_id的问题,同时完美实现「先按品牌分组,再在品牌内按颜色分组」的需求。
首先给你直接上优化后的完整聚合管道,你可以直接套用(根据你的实际统计需求调整细节):
db.yourCollectionName.aggregate([ // 第一步:先按「品牌+颜色」组合分组,计算每个组合的基础统计 { $group: { _id: { make: "$make", color: "$color" }, count: { $sum: 1 } // 这里换成你需要的统计逻辑,比如$avg、$sum某个字段都行 } }, // 第二步:按品牌重新分组,把该品牌下所有颜色的统计结果收集到数组里 { $group: { _id: "$_id.make", colors: { $push: { _id: "$_id.color", count: "$count" // 和第一步的统计字段对应 } } } }, // 可选步骤:重命名字段让输出更友好(把_id改成make) { $project: { _id: 0, make: "$_id", colors: 1 } } ])
接下来给你拆解一下为什么这么写:
- 第一步分组:先把「品牌+颜色」作为联合主键分组,这样我们能先拿到每个品牌下每个颜色的独立统计数据,这一步是避免嵌套分组混乱的关键——先把最细粒度的统计做出来,再往上聚合。
- 第二步分组:这一步才是按品牌做上层分组,用
$push把每个颜色的统计结果(包括正确的颜色值作为_id)塞进colors数组里,这样就解决了你之前颜色_id不正确的问题。 - 可选的$project:如果你的预期结果里希望用
make而不是_id来标识品牌,就加上这一步,让输出结构更贴近你的预期。
举个例子,假设你的原始数据是:
{ make: "Toyota", color: "red", price: 20000 }, { make: "Toyota", color: "red", price: 25000 }, { make: "Toyota", color: "blue", price: 30000 }, { make: "Honda", color: "black", price: 18000 }
用上面的查询(把count换成totalPrice: { $sum: "$price" }),输出会是:
[ { "make": "Toyota", "colors": [ { "_id": "red", "totalPrice": 45000 }, { "_id": "blue", "totalPrice": 30000 } ] }, { "make": "Honda", "colors": [ { "_id": "black", "totalPrice": 18000 } ] } ]
完全符合你要的「品牌分组内再按颜色分组」的结构,而且颜色的_id就是正确的颜色值啦。
内容的提问来源于stack exchange,提问作者Krimson
相关产品推荐
相关产品推荐

