MongoDB聚合查询优化求助:获取总记录数、过滤数据及统计数
优化聚合查询方案
原查询的问题在于过早使用$group阶段:第一个$group会把所有产品文档合并成一个仅包含总记录数的文档,后续的$match、$project等阶段都是基于这个单一文档操作,自然拿不到产品的具体字段,最终返回空结构。
要同时获取「总记录数」「过滤后记录数」「分页产品数据」,推荐使用MongoDB的$facet聚合阶段,它允许在一个聚合操作中并行运行多个独立的管道,一次性输出所有需要的结果。
优化后的代码
let result = await Product.aggregate([ { $facet: { // 统计集合总记录数 totalRecords: [ { $count: "value" } ], // 统计过滤后的记录数 filteredRecords: [ { $match: queries }, { $count: "value" } ], // 获取分页后的产品数据 paginatedProducts: [ { $match: queries }, { $sort: { _id: -1 } }, { $skip: (currentPage - 1) * productsPerPage }, { $limit: productsPerPage }, { $project: { name: 1, description: 1, smallImage: 1, rPriceTM: 1, discount: 1, discountRate: 1, dPriceTM: 1, isNewProduct: 1 } } ] } }, // 整理结果格式,把数组中的统计值提取出来 { $project: { totalRecords: { $arrayElemAt: ["$totalRecords.value", 0] }, filteredRecords: { $arrayElemAt: ["$filteredRecords.value", 0] }, paginatedProducts: 1 } } ])
代码说明
$facet下的三个管道独立执行:totalRecords:直接用$count统计整个集合的总条数filteredRecords:先应用过滤条件$match,再统计过滤后的条数paginatedProducts:先过滤,再排序、分页,最后投影需要的产品字段
- 最后用
$project和$arrayElemAt把统计管道返回的数组值($count会返回单元素数组)提取为单个数值,让结果结构更直观
返回结果示例
[ { totalRecords: 100, // 集合总记录数 filteredRecords: 20, // 过滤后的总记录数 paginatedProducts: [ // 当前页的产品数组 { name: "产品A", ... }, { name: "产品B", ... } ] } ]
内容的提问来源于stack exchange,提问作者Goch
相关产品推荐
相关产品推荐

