spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

How to test if a value is null in aggregation?

Open rChaoz opened this issue 1 year ago • 2 comments

How can I check if a field reference/aggregation expression is null and obtain a boolean?

  • ConditionalOperators.ifNull("field").then(false) - does not return true/false
  • ComparisonOperators.valueOf("field").equalToValue(null) - throws NPE
  • BooleanOperators.Or.or(Fields.field("field")) - also returns true if value is 0

I just want to obtain $eq: ["$field", null]. Am I missing something?

Workaround

ArrayOperators.arrayOf(List.of("null", "missing")).containsValue((DataTypeOperators.typeOf("field")));

But this results in a different query, I'd like to obtain exactly $eq: ["$field", null].

rChaoz avatar Nov 28 '24 08:11 rChaoz

Thanks for bringing this to our attention. There does not seem to be an easy way to do this other than providing your own AggregationExpression.

AggregationUpdate update = AggregationUpdate.update()
    .set(SetOperation.builder().set("field").toValue(new AggregationExpression() {
        @Override
        public org.bson.Document toDocument(AggregationOperationContext context) {
            ArrayList<Object> args = new ArrayList<>(2);
            args.add("$field");
            args.add(null);
            return new org.bson.Document("$eq", args);
        }
    }));

We'll look into lifting the restriction on the Eq expression.

christophstrobl avatar Dec 02 '24 13:12 christophstrobl

The following worked for me:

BooleanOperators.Not.not(Eq.valueOf("field_id").equalToValue(BsonNull.VALUE)),

Translates into:

{ "$not" : [{ "$eq" : ["$field_id", null] }] }

WildDev avatar Apr 25 '25 08:04 WildDev