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

MongoDB聚合中$project与$match阶段未按预期工作问题

问题原因及解决方案

你的查询返回空结果的核心原因是:$match阶段的常规语法无法引用聚合阶段生成的计算字段。你在$match中写的"$firstDayOfLastMonth"会被MongoDB当成字符串字面量,而不是之前$project生成的字段引用,自然匹配不到数据。

下面是两种可行的解决方法:

方法一:用$expr在$match中实现字段比较

通过$expr包裹比较逻辑,就能让$match识别聚合生成的字段:

db.user_activity_trackings.aggregate([
  {
    $project: {
      "firstDayOfLastMonth": {
        "$dateFromParts": {
          "year": { "$year": { "$dateAdd": { "startDate": "$$NOW", "unit": "month", "amount": -1 } } },
          "month": { "$month": { "$dateAdd": { "startDate": "$$NOW", "unit": "month", "amount": -1 } } },
          "day": 1
        }
      },
      "createdAt": 1
    }
  },
  {
    $match: {
      $expr: { $gte: ["$createdAt", "$firstDayOfLastMonth"] }
    }
  }
])

方法二:提前计算上月1日,直接作为常量过滤(更高效)

这种方式不需要为每个文档计算上月1日,能减少聚合计算开销,推荐使用:

客户端计算后传入(适合多数场景)

// 先计算上月1日的零时日期
const firstDayOfLastMonth = new Date();
firstDayOfLastMonth.setMonth(firstDayOfLastMonth.getMonth() - 1);
firstDayOfLastMonth.setDate(1);
firstDayOfLastMonth.setHours(0, 0, 0, 0);

// 执行聚合查询
db.user_activity_trackings.aggregate([
  {
    $match: {
      createdAt: { $gte: firstDayOfLastMonth }
    }
  }
])

纯聚合语法实现(不依赖客户端)

db.user_activity_trackings.aggregate([
  {
    $match: {
      $expr: {
        $gte: [
          "$createdAt",
          {
            $dateFromParts: {
              year: { $year: { $dateAdd: { startDate: "$$NOW", unit: "month", amount: -1 } } },
              month: { $month: { $dateAdd: { startDate: "$$NOW", unit: "month", amount: -1 } } },
              day: 1
            }
          }
        ]
      }
    }
  }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 19:57:15