MongoDB聚合$group去重分组后按条件统计文档的方法
解决方案
要给最多25条的分页结果添加对应分组的全集合未读消息统计字段newField,可以通过MongoDB的$facet聚合操作同时完成全局统计与分页查询,再将两者关联,具体实现如下:
聚合管道代码
db.your_collection_name.aggregate([ { $facet: { // 分支1:统计全集合内每个roommates分组的未读消息数量 unreadStats: [ { $group: { // 以文档的_id(即roommates数组)作为分组键;若需忽略数组顺序,可改用$sortArray排序后分组 _id: "$_id", newField: { $sum: { $cond: [{ $eq: ["$viewed", false] }, 1, 0] } } } } ], // 分支2:获取分页后的目标结果(最多25条,可按需调整排序规则) paginatedResults: [ { $sort: { created_at: -1 } }, { $limit: 25 } ] } }, // 展开分页结果文档 { $unwind: "$paginatedResults" }, // 关联当前分页文档对应的未读统计数据 { $lookup: { from: "$unreadStats", localField: "paginatedResults._id", foreignField: "_id", as: "matchedStats" } }, { $unwind: "$matchedStats" }, // 合并分页文档与统计字段,生成最终结果 { $replaceRoot: { newRoot: { $mergeObjects: [ "$paginatedResults", { newField: "$matchedStats.newField" } ] } } } ])
关键说明
- $facet的作用:在单个聚合管道内同时执行两个独立分支,分别完成全局未读统计和分页查询,避免多次访问数据库。
- 分组规则调整:如果
roommates数组顺序不影响分组(比如[1,2]和[2,1]属于同一分组),可将$group的_id改为{ $sortArray: { input: "$_id", sortBy: 1 } },用排序后的数组作为统一分组键。 - 分页逻辑自定义:
paginatedResults分支中的$sort和$limit可根据业务需求调整排序字段和条数限制。
内容的提问来源于stack exchange,提问作者kotcich
相关产品推荐
相关产品推荐

