MongoDB嵌套数组统计:保留原文档并统计like类型投票数
解决方案:保留原文档并统计指定类型投票数
方法一:生成你预期的数组嵌套格式
下面的聚合管道可以直接输出你想要的[原文档, 统计对象]结构,同时避免了$unwind带来的性能损耗:
db.getCollection('MyDocument').aggregate([ // 计算当前文档中voteType为like的投票总数 { $addFields: { likeCount: { $size: { $filter: { input: "$votes", cond: { $eq: ["$$this.voteType", "like"] } } } } } }, // 构造目标输出结构 { $project: { result: [ { _id: "$_id", category: "$category", votes: "$votes" }, { sum: "$likeCount", voteType: "like" } ] } }, // 将数组结构设为根文档 { $replaceRoot: { newRoot: "$result" } }, // 按投票数降序排序 { $sort: { "1.sum": -1 } }, // 限制输出前5条 { $limit: 5 } ])
步骤解释
- $addFields:通过
$filter筛选出votes数组中所有voteType为like的元素,再用$size获取筛选结果的长度,得到like投票的总数,新增为likeCount字段。 - $project:将原文档的核心字段(_id、category、votes)和统计对象(包含sum和voteType)组合成一个数组
result。 - $replaceRoot:把
result数组设置为输出的根对象,最终每个输出项就是你想要的数组格式。 - $sort & $limit:按统计的投票数降序排序,并限制输出前5条数据。
方法二:在原文档中新增统计字段(更实用的场景)
如果不需要严格的数组嵌套格式,只是想在原文档中附加统计信息,可以用更简洁的管道:
db.getCollection('MyDocument').aggregate([ { $addFields: { likeVoteStats: { sum: { $size: { $filter: { input: "$votes", cond: { $eq: ["$$this.voteType", "like"] } } } }, voteType: "like" } } }, { $sort: { "likeVoteStats.sum": -1 } }, { $limit: 5 } ])
该管道会在每个原文档中新增likeVoteStats字段,直接包含统计的投票数和类型,使用起来更灵活。
内容的提问来源于stack exchange,提问作者MrBushido
相关产品推荐
相关产品推荐

