如何在MongoDB中合并对象并统计房间访问量分布
MongoDB聚合查询方案:统计房间访问次数分布
需求
合并集合内所有文档的roomVisits对象,完成两步统计:
- 计算每个房间的总访问次数
- 统计拥有相同总访问次数的房间数量,最终输出以「总访问次数」为键、「房间数量」为值的结果。
聚合查询代码
db.collection.aggregate([ // 将roomVisits对象转为键值对数组,方便后续处理 { $project: { roomEntries: { $objectToArray: "$roomVisits" } } }, // 拆分每个房间的访问记录 { $unwind: "$roomEntries" }, // 按房间名称分组,累加总访问次数 { $group: { _id: "$roomEntries.k", totalVisits: { $sum: "$roomEntries.v" } } }, // 按总访问次数分组,统计对应房间数量 { $group: { _id: "$totalVisits", count: { $sum: 1 } } }, // 将结果整理为指定格式 { $group: { _id: null, result: { $arrayToObject: [{ $push: { k: { $toString: "$_id" }, v: "$count" } }] } } }, // 去除冗余的_id字段 { $project: { _id: 0 } } ])
代码阶段解释
- $project + $objectToArray:把每个文档的
roomVisits对象(如{"ROOM4":5})转换成键值对数组(如[{k:"ROOM4",v:5}]),解决动态键无法直接聚合的问题。 - $unwind:将数组拆分为单个文档,每个文档对应一条房间访问记录。
- 第一次$group:按房间名称(
roomEntries.k)分组,累加所有该房间的访问次数,得到每个房间的总访问量。 - 第二次$group:按总访问次数(
totalVisits)分组,统计有多少个房间拥有该访问次数。 - 第三次$group + $arrayToObject:将分组后的结果(如
[{_id:4,count:1},{_id:25,count:1}])转换为对象格式,匹配预期输出结构。 - 最后一次$project:移除不需要的
_id字段,只保留result结果。
验证示例1
针对第一个数据样本,执行查询后会得到:
{ "result": { "4": 1, "25": 1 } }
- ROOM13总访问次数:3+1=4,对应1个房间
- ROOM4总访问次数:5+13+3+4=25,对应1个房间
验证示例2
第二个数据样本执行查询后,会得到与预期完全一致的结果,涵盖所有房间的总访问次数及对应房间数量统计。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

