From 1eca35093c88a642debedd95f32697661d69e12d Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 20 Dec 2024 13:53:09 +0100 Subject: [PATCH] Wrap Criteria is and regex comparison if necessary. This commit wraps simple values and Patterns if to avoid creating invalid query objects. Original pull request: #4862 Closes #4850 --- .../data/mongodb/core/query/Criteria.java | 13 +++++- .../mongodb/core/query/CriteriaUnitTests.java | 40 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) 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 fc25e15c0..3c05c2222 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 @@ -945,8 +945,17 @@ public class Criteria implements CriteriaDefinition { Document queryCriteria = new Document(); if (!NOT_SET.equals(isValue)) { - queryCriteria.put(this.key, this.isValue); - queryCriteria.putAll(document); + if(document.isEmpty()) { + queryCriteria.put(this.key, this.isValue); + } + else { + if(isValue instanceof Pattern || isValue instanceof BsonRegularExpression) { + document.put("$regex", isValue); + } else { + document.put("$eq", isValue); + } + queryCriteria.put(this.key, document); + } } else { queryCriteria.put(this.key, document); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java index 645f75066..14448bb05 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/query/CriteriaUnitTests.java @@ -20,7 +20,9 @@ import static org.springframework.data.mongodb.test.util.Assertions.*; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.regex.Pattern; +import org.bson.BsonRegularExpression; import org.bson.Document; import org.junit.Test; import org.springframework.data.geo.Point; @@ -50,6 +52,44 @@ public class CriteriaUnitTests { assertThat(c.getCriteriaObject()).isEqualTo("{ \"name\" : \"Bubba\"}"); } + @Test // GH-4850 + public void testCombiningSimpleCriteria() { + + Document expected = Document.parse("{ name : { $eq : 123, $type : ['long'] } }"); + + Criteria c = Criteria.where("name") // + .is(123) // + .type(Type.INT_64); + + assertThat(c.getCriteriaObject()).isEqualTo(expected); + + c = Criteria.where("name") // + .type(Type.INT_64) + .is(123); + + assertThat(c.getCriteriaObject()).isEqualTo(expected); + } + + @Test // GH-4850 + public void testCombiningBsonRegexCriteria() { + + Criteria c = Criteria.where("name") + .regex(new BsonRegularExpression("^spring$")) + .type(Type.INT_64); + + assertThat(c.getCriteriaObject()).isEqualTo(Document.parse("{ name : { $regex : RegExp('^spring$'), $type : ['long'] } }")); + } + + @Test // GH-4850 + public void testCombiningRegexCriteria() { + + Criteria c = Criteria.where("name") + .regex("^spring$") + .type(Type.INT_64); + + assertThat(c.getCriteriaObject()).hasEntrySatisfying("name.$regex", it -> assertThat(it).isInstanceOf(Pattern.class)); + } + @Test public void testNotEqualCriteria() { Criteria c = new Criteria("name").ne("Bubba");