You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:25:09