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;