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

如何实现MongoDB文档的投影与分对象聚合查询?

正确的MongoDB聚合查询实现方案

原代码问题分析

  • 连续使用两次$facet导致过滤后的数据集被重复处理,性能损耗明显
  • 第二个$facet的$project阶段引用了不存在的_count字段,逻辑错误
  • 聚合计数逻辑缺失,无法生成符合预期的aggregates结构

正确聚合查询实现

const res = await BusDayWiseBreakDown.aggregate([
  {
    $match: {
      varId,
      status
    }
  },
  {
    $facet: {
      // 生成目标结果数组,只保留指定字段
      result: [
        {
          $project: {
            _id: 1,
            varId: 1,
            status: 1
          }
        }
      ],
      // 计算聚合统计值
      aggregates: [
        {
          $group: {
            _id: null,
            _count: { $sum: 1 },
            collection: { $sum: "$collection" },
            cash: { $sum: "$cash" },
            upi: { $sum: "$upi" },
            driverSalary: { $sum: "$driverSalary" }
          }
        },
        {
          $project: {
            _id: 0 // 移除分组生成的冗余_id字段
          }
        }
      ]
    }
  },
  {
    // 将聚合结果数组转为单个对象($group后返回的是单元素数组)
    $addFields: {
      aggregates: { $arrayElemAt: ["$aggregates", 0] }
    }
  }
]).session(mongoSession);

return res[0]; // 聚合返回数组,取第一个元素即为目标结构

代码逻辑说明

  1. $match阶段:先过滤出符合varId和status条件的文档,减少后续处理的数据量,从根源提升性能
  2. $facet阶段:并行执行两个处理分支,避免重复遍历数据集:
    • result分支:通过$project直接保留需要的三个字段,生成目标结果数组
    • aggregates分支:
      • $group:以null为分组键,一次性计算文档计数_count和各数值字段的总和
      • $project:移除分组自动生成的_id字段,整理聚合结果格式
  3. $addFields阶段:将aggregates的单元素数组转为单个对象,匹配预期输出结构
  4. 最后返回聚合结果数组的第一个元素,得到符合需求的完整结构

内容的提问来源于stack exchange,提问作者Roomi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:31:07