如何在MongoDB聚合查询中添加总计数且保留其他聚合数据
问题根源
你当前代码的核心问题是 $count 聚合阶段的特性与执行顺序错误:
$count阶段会将上游输出的所有文档,直接替换为仅包含count字段的单个文档,执行完该阶段后你原来的业务数据已经全部被清空,后续的排序、分页逻辑自然无法生效- 额外注意:你当前的聚合阶段顺序也存在逻辑错误,
$sort、$skip、$limit分页相关逻辑应该放在计数逻辑之前执行,否则计数会统计所有符合条件的数据,而非分页后的结果
修正方案
使用$facet阶段实现「同时保留总计数和分页数据」的需求,$facet可以并行执行多个独立的子聚合管道,互不影响,修正后的代码如下:
products = await StorageModel.aggregate([ // 原有业务逻辑保留不动 { $lookup: { from: "catalogs", localField: "catalogProduct", foreignField: "_id", as: "catalogs" }}, // 可选优化:如果catalogProduct是一对一关联,加$unwind把catalogs数组转成对象,避免后续嵌套数组取值异常 // { $unwind: "$catalogs" }, { $lookup: { from: "categories", localField: "catalogs.category", foreignField: "_id", as: "catalogs.category" }}, { $addFields: { "catalogs.category": "$catalogs.category" }}, { $match: { "catalogs.category._id": { $in: ids } }}, { $lookup: { from: "catalogs", localField: "catalogProduct", foreignField: "_id", as: "catalogProductNew" }}, // 新增$facet并行执行两个子管道 { $facet: { // 子管道1:统计符合条件的总条数 totalCount: [ { $count: "count" } ], // 子管道2:处理排序、分页,保留完整业务数据 paginatedData: [ { $sort: { _id: -1 } }, { $skip: (page - 1) * 8 }, { $limit: 8 } ] }}, // 可选优化:把totalCount转成纯数字格式,方便前端直接取用 { $addFields: { totalCount: { $arrayElemAt: ["$totalCount.count", 0] } }} ]);
返回结果说明
修正后返回的结果格式如下:
[ { totalCount: 3, // 符合条件的总条数 paginatedData: [ // 当前分页的业务数据,包含所有嵌套字段 // ... 完整的StorageModel数据 ] } ]
你可以根据业务需要直接提取对应字段使用即可。
内容的提问来源于stack exchange,提问作者Evgeny Alekseev
相关产品推荐
相关产品推荐

