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

