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
相关产品推荐
相关产品推荐

