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

Spring Data MongoDB:聚合过滤数组中字段为null或不存在的元素

解决Spring Data MongoDB中$filter筛选null或不存在字段的问题

你遇到的ComparisonOperators.lessThanEqualToValue不接受null的问题,其实可以换个思路——MongoDB的聚合表达式中,$eq匹配null时,会同时命中字段不存在和字段值为null的元素,完全满足你的需求,不需要用lessThanEqualTo。

下面是两种可行的实现方式:

方式一:用Spring Data操作符封装实现

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.ComparisonOperators;

// 构建聚合管道
Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.project()
        .and(Aggregation.filter("versions")
            .as("v")
            // 直接匹配terminationDate为null或不存在的情况
            .by(ComparisonOperators.Eq.valueOf("$$v.terminationDate").equalToValue(null))
        ).as("activeVersions")
);

方式二:直接构造原生MongoDB表达式(兼容低版本Spring Data)

如果你的Spring Data MongoDB版本较低,操作符封装不全,可以直接用AggregationExpression构造原生的聚合逻辑:

import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationExpression;
import org.springframework.data.mongodb.core.aggregation.AggregationOperationContext;
import org.bson.Document;
import java.util.Arrays;

Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.project()
        .and((AggregationExpression) context -> new Document("$filter",
            new Document("input", "$versions")
                .append("as", "v")
                .append("cond", new Document("$eq", Arrays.asList("$$v.terminationDate", null)))
        )).as("activeVersions")
);

补充说明

如果你确实需要分开判断(比如某些特殊场景),也可以用$or组合两个条件:

import org.springframework.data.mongodb.core.aggregation.ConditionalOperators;
import org.springframework.data.mongodb.core.aggregation.FieldOperators;

Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.project()
        .and(Aggregation.filter("versions")
            .as("v")
            .by(ConditionalOperators.or(
                ComparisonOperators.Eq.valueOf("$$v.terminationDate").equalToValue(null),
                ConditionalOperators.not(FieldOperators.Exists.valueOf("$$v.terminationDate").exists())
            ))
        ).as("activeVersions")
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 21:30:32