MongoDB聚合能否统计数组重复元素的出现次数?
用MongoDB聚合实现数组元素频次统计
当然可以!MongoDB的聚合框架完全能帮你实现这个需求,而且步骤清晰易懂。
假设你的数据存储在一个集合(比如叫myCollection)中,文档结构如下(数组字段这里命名为elements,你可以根据实际字段名调整):
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "elements": [ 'gg', 'bb', 'dd', 'cc', 'll', 'aa', 'cc', 'gg', 'bb', 'dd', 'cc', 'bb', 'dd', 'll', 'aa' ] }
下面是具体的聚合管道代码,能直接输出你想要的键值对格式结果:
db.myCollection.aggregate([ // 1. 将数组拆分为单个元素的文档 { $unwind: "$elements" }, // 2. 按元素分组,统计出现次数 { $group: { _id: "$elements", count: { $sum: 1 } } }, // 3. 将统计结果整理为[{k: 元素, v: 次数}]的数组格式 { $group: { _id: null, counts: { $push: { k: "$_id", v: "$count" } } } }, // 4. 将数组转换为键值对对象,并替换为根文档 { $replaceRoot: { newRoot: { $arrayToObject: "$counts" } } } ])
步骤解释:
$unwind:把数组中的每个元素单独拆分成一条文档,这样原本的1条文档会变成15条,每条只包含一个elements值。- 第一次
$group:以数组元素的值为分组依据,用$sum:1累加每组的文档数量,得到每个元素的出现次数。 - 第二次
$group:把所有统计项收集到一个数组里,每个数组元素是{k: 元素名, v: 次数}的结构——这是MongoDB中$arrayToObject函数要求的格式。 $replaceRoot+$arrayToObject:把数组转换为你需要的键值对对象,最终输出结果就是:{ 'gg': 2, 'bb': 3, 'dd': 3, 'cc': 3, 'll': 2, 'aa': 2 }
额外说明:
如果你的集合中有多个包含这类数组的文档,且需要统计全局所有数组元素的总频次,直接运行上面的代码即可;如果只想统计单个特定文档的数组,只需在管道最开头加上$match阶段来匹配目标文档:
db.myCollection.aggregate([ { $match: { _id: ObjectId("你的目标文档ID") } }, // 先匹配目标文档 { $unwind: "$elements" }, // 后续步骤和上面一致... ])
内容的提问来源于stack exchange,提问作者Harry Htoo
相关产品推荐
相关产品推荐

