From efa9a2d40877f78a95e4b9314ed7ae5ff2ed23c1 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 4 May 2021 14:29:52 +0200 Subject: [PATCH] Add Criteria.isNullValue() as alternative to Criteria.is(null). See #3633 Original pull request: #3643. --- .../data/mongodb/core/query/Criteria.java | 37 +++++++++++++++++++ .../core/convert/QueryMapperUnitTests.java | 13 ++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java index b0a1b4989..9b1e8df94 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/Criteria.java @@ -29,6 +29,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.bson.BsonRegularExpression; +import org.bson.BsonType; import org.bson.Document; import org.bson.types.Binary; import org.springframework.data.domain.Example; @@ -188,6 +189,42 @@ public class Criteria implements CriteriaDefinition { return this; } + /** + * Creates a criterion using {@literal null} equality comparison which matches documents that either contain the item + * field whose value is {@literal null} or that do not contain the item field. + *

+ * Use {@link #isNullValue()} to only query for documents that contain the field whose value is equal to + * {@link org.bson.BsonType#NULL}.
+ * Use {@link #exists(boolean)} to query for documents that do (not) contain the field. + * + * @return this. + * @see Query for Null or + * Missing Fields: Equality Filter + * @since 3.3 + */ + public Criteria isNull() { + return is(null); + } + + /** + * Creates a criterion using a {@link org.bson.BsonType} comparison which matches only documents that contain the item + * field whose value is equal to {@link org.bson.BsonType#NULL}. + *

+ * Use {@link #isNull()} to query for documents that contain the field with a {@literal null} value or do not contain the + * field at all.
+ * Use {@link #exists(boolean)} to query for documents that do (not) contain the field. + * + * @return this. + * @see Query for Null or Missing + * Fields: Type Check + * @since 3.3 + */ + public Criteria isNullValue() { + + criteria.put("$type", BsonType.NULL.getValue()); + return this; + } + private boolean lastOperatorWasNot() { return !this.criteria.isEmpty() && "$not".equals(this.criteria.keySet().toArray()[this.criteria.size() - 1]); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java index 8c23b4a22..dd8dd25e8 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/QueryMapperUnitTests.java @@ -1258,7 +1258,7 @@ public class QueryMapperUnitTests { @Test // GH-3633 void mapsNullValueForFieldWithCustomTargetType() { - Query query = query(where("stringAsOid").is(null)); + Query query = query(where("stringAsOid").isNull()); org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(NonIdFieldWithObjectIdTargetType.class)); @@ -1266,6 +1266,17 @@ public class QueryMapperUnitTests { assertThat(document).isEqualTo(new org.bson.Document("stringAsOid", null)); } + @Test // GH-3633 + void mapsNullBsonTypeForFieldWithCustomTargetType() { + + Query query = query(where("stringAsOid").isNullValue()); + + org.bson.Document document = mapper.getMappedObject(query.getQueryObject(), + context.getPersistentEntity(NonIdFieldWithObjectIdTargetType.class)); + + assertThat(document).isEqualTo(new org.bson.Document("stringAsOid", new org.bson.Document("$type", 10))); + } + class WithDeepArrayNesting { List level0;