如何使用Mongoose Aggregate对数组内对象字段求和并新增总数字段
基础场景实现(articles数组已带views字段)
如果你的作者文档中articles数组已经直接存储了每篇文章的浏览量数值,只需要加一个$addFields阶段结合$sum数组表达式即可实现需求:
Author.aggregate([ // 你原有的其他聚合阶段 { $addFields: { totalArticleViews: { $sum: "$articles.views" } } } ])
嵌套Lookup场景实现(文章、浏览量分属不同模型)
按照你要求的「在views查询的子管道内直接累加总浏览量」的需求,可以在内部lookup后先统计单篇文章浏览量,再通过$facet算子在子管道内同时保留文章完整数据、计算总浏览量,完整实现如下:
Author.aggregate([ { $lookup: { from: 'articles', as: 'articleTempData', let: { authorId: "$_id" }, pipeline: [ // 匹配当前作者的所有文章 { $match: { $expr: { $eq: ["$author", "$$authorId"] } } }, // 关联每篇文章对应的浏览量记录 { $lookup: { from: 'views', localField: '_id', foreignField: 'document', as: 'views' } }, // 计算单篇文章的总浏览量 { $addFields: { // 如果views集合每条记录对应一次浏览,没有单独的计数字段,替换为{ $size: "$views" } singleArticleViews: { $sum: "$views.viewCount" } } }, // 子管道内同时生成文章列表、总浏览量统计 { $facet: { articles: [], // 空管道保留所有文章的完整字段 totalViewCount: [ { $group: { _id: null, sum: { $sum: "$singleArticleViews" } } }, { $project: { _id: 0 } } ] } } ] } }, // 将临时数据中的字段提取到根层级 { $addFields: { articles: { $first: "$articleTempData.articles" }, totalArticleViews: { $first: "$articleTempData.totalViewCount.sum" } } }, // 删除临时字段 { $project: { articleTempData: 0 } } ])
说明
- 所有统计逻辑完全在articles查询的子管道内完成,不需要在关联完所有数据后再单独做统计
- 如果你的views集合中没有单独的浏览量计数字段,每条记录就代表一次浏览,把
singleArticleViews的计算逻辑替换为{ $size: "$views" }即可 - 代码中的
viewCount请替换为你实际存储浏览量数值的字段名
内容的提问来源于stack exchange,提问作者samman adhikari
相关产品推荐
相关产品推荐

