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

MongoDB聚合中$expr查询子文档数组无结果问题求助

问题原因

在MongoDB中,普通的'subDocumentArray.createdAt': {$gt: ...}查询会自动处理数组字段——它会检查数组中是否存在至少一个子文档的createdAt满足条件。但当你在$expr中直接引用$subDocumentArray.createdAt时,MongoDB会把它解析为整个数组的所有日期值组成的集合,而不是逐个元素进行比较。由于集合(数组)和单个日期值无法直接通过$gte进行有效比较,所以返回结果为空。

而针对顶级属性的$expr查询能正常工作,是因为顶级属性是单个值,和$dateTrunc返回的单个日期值可以直接做比较。

修改方案

要在$expr中实现对数组子文档的条件筛选,需要使用数组遍历操作符来逐个检查元素。以下是两种可行的写法:

方法1:使用$anyElementTrue + $map

通过$map遍历数组中的每个子文档,判断其createdAt是否满足条件,再用$anyElementTrue检查是否存在至少一个符合条件的元素:

{
  $match: {
    $expr: {
      $anyElementTrue: {
        $map: {
          input: "$subDocumentArray",
          as: "item",
          in: {
            $gte: [
              "$$item.createdAt",
              { $dateTrunc: { date: "$$NOW", unit: "month" } }
            ]
          }
        }
      }
    }
  }
}

方法2:使用$filter + $size

通过$filter筛选出符合条件的子文档,再判断筛选后的数组长度是否大于0:

{
  $match: {
    $expr: {
      $gt: [
        {
          $size: {
            $filter: {
              input: "$subDocumentArray",
              cond: {
                $gte: [
                  "$$this.createdAt",
                  { $dateTrunc: { date: "$$NOW", unit: "month" } }
                ]
              }
            }
          }
        },
        0
      ]
    }
  }
}

这两种写法都能实现和硬编码查询相同的逻辑:筛选出至少有一个子文档createdAt大于等于当月第一天的文档。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 12:55:19