MongoDB聚合:统计单文档子数组中不同值的出现次数
解决MongoDB中每个文档内数组元素的分组计数问题
我明白你想要的效果——给每个文档单独统计colors数组里不同color值的出现次数,而不是全局总计。这里有个用MongoDB聚合管道实现的方案,完全符合你的预期结果:
db.collection.aggregate([ { $addFields: { colors: { $arrayToObject: { $map: { input: { $setUnion: ["$colors.color"] }, as: "color", in: { k: "$$color", v: { $size: { $filter: { input: "$colors", cond: { $eq: ["$$this.color", "$$color"] } } } } } } } } } } ])
分步解释这个聚合管道:
- $addFields:用来替换原有的
colors字段,同时自动保留文档里的其他所有字段(比如_id、name),比用$project手动列出所有要保留的字段更高效。 - $setUnion:先从
colors数组中提取所有不重复的color值,得到我们需要统计的颜色列表。 - $map:遍历每个不重复的颜色,生成一个包含
k(颜色名称)和v(对应计数)的键值对对象。 - $filter + $size:针对每个颜色,过滤出
colors数组中匹配该颜色的所有元素,再用$size获取匹配元素的数量,也就是这个颜色的出现次数。 - $arrayToObject:把
$map生成的键值对数组转换成你想要的对象格式(比如{Blue: 2, Red: 1})。
运行这个管道后,就能得到你期望的结果:每个文档的colors字段变成对应颜色的计数对象,其他字段完全保留原样。
内容的提问来源于stack exchange,提问作者Tomislav Nekic
相关产品推荐
相关产品推荐

