MongoDB聚合操作中统计记录内hashtag、lang、username出现次数问题
MongoDB 聚合实现方案
实现逻辑
- 先展开hashtags数组,保证单文档内多个标签可单独计数
- 按hour字段分组,收集分组内所有文档的标签、语言、用户名以及不重复文档ID
- 分别统计各标签、语言、用户名的出现次数,将统计结果转换为键值对对象后按字母升序排序键
- 补充默认统计字段,调整输出格式
完整聚合语句
db.item.aggregate([ // 展开hashtags数组 { $unwind: "$hashtags" }, // 按hour分组 { $group: { _id: "$hour", // 收集不重复文档ID用于统计总推文数 docIds: { $addToSet: "$_id" }, // 收集所有待统计字段值 allHashtags: { $push: "$hashtags" }, allLangs: { $push: "$lang" }, allUsernames: { $push: "$username" } } }, // 格式转换与统计 { $project: { _id: { hour: "$_id" }, // 统计总推文数 nbTweets: { $size: "$docIds" }, // 标签统计+按键排序 hashtags: { $arrayToObject: { $sortArray: { input: { $map: { input: { $setUnion: "$allHashtags" }, as: "tag", in: { k: "$$tag", v: { $size: { $filter: { input: "$allHashtags", cond: { $eq: ["$$this", "$$tag"] } } } } } } }, sortBy: { k: 1 } } } }, // 语言统计+按键排序 languages: { $arrayToObject: { $sortArray: { input: { $map: { input: { $setUnion: "$allLangs" }, as: "lang", in: { k: "$$lang", v: { $size: { $filter: { input: "$allLangs", cond: { $eq: ["$$this", "$$lang"] } } } } } } }, sortBy: { k: 1 } } } }, // 用户名统计+按键排序 usernames: { $arrayToObject: { $sortArray: { input: { $map: { input: { $setUnion: "$allUsernames" }, as: "user", in: { k: "$$user", v: { $size: { $filter: { input: "$allUsernames", cond: { $eq: ["$$this", "$$user"] } } } } } } }, sortBy: { k: 1 } } } }, // 补充默认值字段 nbLikes: { $literal: 0 }, nbQuotes: { $literal: 0 }, nbRetweets: { $literal: 0 } } }, // 可选:按时间倒序输出结果 { $sort: { "_id.hour": -1 } } ])
说明
- $setUnion 用于提取分组内不重复的字段值,避免重复遍历
- $sortArray 对键值对数组按key升序排列,满足字母排序要求
- 用$addToSet收集文档ID再统计长度,避免unwind导致的总推文数统计错误
内容的提问来源于stack exchange,提问作者Martin Ratinaud
相关产品推荐
相关产品推荐

