diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java
index 19d14bdb4..0ef55b6a1 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java
@@ -686,19 +686,63 @@ public class StringOperators {
private RegexMatch createRegexMatch() {
return usesFieldRef() ? RegexMatch.valueOf(fieldReference) : RegexMatch.valueOf(expression);
}
-
- public ReplaceOne replaceOne(String find,String replacement) {
- return createReplaceOne().find(find).replacement(replacement);
+
+ /**
+ * Creates new {@link AggregationExpression} that takes the associated string representation and replaces the first
+ * occurrence of the search string with the given replacement.
+ *
+ * @param search
+ * @param replacement
+ * @return new instance of {@link ReplaceOne}.
+ * @since 3.4
+ */
+ public ReplaceOne replaceOne(String search, String replacement) {
+ return createReplaceOne().find(search).replacement(replacement);
}
-
+
+ /**
+ * Creates new {@link AggregationExpression} that takes the associated string representation and replaces the first
+ * occurrence of the search string computed by the given {@link AggregationExpression} with the given replacement.
+ *
+ * @param search
+ * @param replacement
+ * @return new instance of {@link ReplaceOne}.
+ * @since 3.4
+ */
+ public ReplaceOne replaceOne(AggregationExpression search, String replacement) {
+ return createReplaceOne().findValueOf(search).replacement(replacement);
+ }
+
private ReplaceOne createReplaceOne() {
return usesFieldRef() ? ReplaceOne.valueOf(fieldReference) : ReplaceOne.valueOf(expression);
}
-
- public ReplaceAll replaceAll(String find,String replacement) {
- return createReplaceAll().find(find).replacement(replacement);
+
+ /**
+ * Creates new {@link AggregationExpression} that takes the associated string representation and replaces all
+ * occurrences of the search string with the given replacement.
+ *
+ * @param search
+ * @param replacement
+ * @return new instance of {@link ReplaceOne}.
+ * @since 3.4
+ */
+ public ReplaceAll replaceAll(String search, String replacement) {
+ return createReplaceAll().find(search).replacement(replacement);
}
-
+
+ /**
+ * Creates new {@link AggregationExpression} that takes the associated string representation and replaces all
+ * occurrences of the search string computed by the given {@link AggregationExpression} with the given replacement.
+ *
+ * @param search
+ * @param replacement
+ * @return new instance of {@link ReplaceOne}.
+ * @since 3.4
+ */
+ public ReplaceAll replaceAll(AggregationExpression search, String replacement) {
+ return createReplaceAll().findValueOf(search).replacement(replacement);
+ }
+
private ReplaceAll createReplaceAll() {
return usesFieldRef() ? ReplaceAll.valueOf(fieldReference) : ReplaceAll.valueOf(expression);
}
@@ -706,8 +750,6 @@ public class StringOperators {
private boolean usesFieldRef() {
return fieldReference != null;
}
-
-
}
/**
@@ -2096,11 +2138,15 @@ public class StringOperators {
return "$regexMatch";
}
}
-
+
/**
* {@link AggregationExpression} for {@code $replaceOne} which replaces the first instance of a search string in an
* input string with a replacement string.
* NOTE: Requires MongoDB 4.4 or later.
+ *
+ * @author Divya Srivastava
+ * @author Christoph Strobl
+ * @since 3.4
*/
public static class ReplaceOne extends AbstractAggregationExpression {
@@ -2108,6 +2154,19 @@ public class StringOperators {
super(value);
}
+ /**
+ * Creates new {@link ReplaceOne} using the given as {@literal input}.
+ *
+ * @param value must not be {@literal null}.
+ * @return new instance of {@link ReplaceOne}.
+ */
+ public static ReplaceOne value(String value) {
+
+ Assert.notNull(value, "Value must not be null!");
+
+ return new ReplaceOne(Collections.singletonMap("input", value));
+ }
+
/**
* Creates new {@link ReplaceOne} using the value of the provided {@link Field fieldReference} as {@literal input}
* value.
@@ -2180,25 +2239,23 @@ public class StringOperators {
/**
* The string to search for within the given input field.
*
- * @param find must not be {@literal null}.
+ * @param value must not be {@literal null}.
* @return new instance of {@link ReplaceOne}.
*/
- public ReplaceOne find(String searchStr) {
+ public ReplaceOne find(String value) {
- Assert.notNull(searchStr, "Search string must not be null!");
+ Assert.notNull(value, "Search string must not be null!");
- Map search = append("find", searchStr);
-
- return new ReplaceOne(search);
+ return new ReplaceOne(append("find", value));
}
/**
* Specify the reference to the {@link Field field} holding the string to search for within the given input field.
*
- * @param find must not be {@literal null}.
+ * @param fieldReference must not be {@literal null}.
* @return new instance of {@link ReplaceOne}.
*/
- public ReplaceOne findOf(String fieldReference) {
+ public ReplaceOne findValueOf(String fieldReference) {
Assert.notNull(fieldReference, "fieldReference must not be null!");
@@ -2212,7 +2269,7 @@ public class StringOperators {
* @param expression must not be {@literal null}.
* @return new instance of {@link ReplaceOne}.
*/
- public ReplaceOne findOf(AggregationExpression expression) {
+ public ReplaceOne findValueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
@@ -2224,11 +2281,15 @@ public class StringOperators {
return "$replaceOne";
}
}
-
+
/**
* {@link AggregationExpression} for {@code $replaceAll} which replaces all instances of a search string in an input
* string with a replacement string.
* NOTE: Requires MongoDB 4.4 or later.
+ *
+ * @author Divya Srivastava
+ * @author Christoph Strobl
+ * @since 3.4
*/
public static class ReplaceAll extends AbstractAggregationExpression {
@@ -2236,6 +2297,19 @@ public class StringOperators {
super(value);
}
+ /**
+ * Creates new {@link ReplaceAll} using the given as {@literal input}.
+ *
+ * @param value must not be {@literal null}.
+ * @return new instance of {@link ReplaceOne}.
+ */
+ public static ReplaceAll value(String value) {
+
+ Assert.notNull(value, "Value must not be null!");
+
+ return new ReplaceAll(Collections.singletonMap("input", value));
+ }
+
/**
* Creates new {@link ReplaceAll} using the value of the provided {@link Field fieldReference} as {@literal input}
* value.
@@ -2284,7 +2358,7 @@ public class StringOperators {
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link ReplaceAll}.
*/
- public ReplaceAll replacementOf(String fieldReference) {
+ public ReplaceAll replacementValueOf(String fieldReference) {
Assert.notNull(fieldReference, "FieldReference must not be null!");
@@ -2298,7 +2372,7 @@ public class StringOperators {
* @param expression must not be {@literal null}.
* @return new instance of {@link ReplaceAll}.
*/
- public ReplaceAll replacementOf(AggregationExpression expression) {
+ public ReplaceAll replacementValueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
@@ -2308,25 +2382,23 @@ public class StringOperators {
/**
* The string to search for within the given input field.
*
- * @param find must not be {@literal null}.
+ * @param value must not be {@literal null}.
* @return new instance of {@link ReplaceAll}.
*/
- public ReplaceAll find(String searchStr) {
+ public ReplaceAll find(String value) {
- Assert.notNull(searchStr, "Search string must not be null!");
+ Assert.notNull(value, "Search string must not be null!");
- Map search = append("find", searchStr);
-
- return new ReplaceAll(search);
+ return new ReplaceAll(append("find", value));
}
/**
* Specify the reference to the {@link Field field} holding the string to search for within the given input field.
*
- * @param find must not be {@literal null}.
+ * @param fieldReference must not be {@literal null}.
* @return new instance of {@link ReplaceAll}.
*/
- public ReplaceAll findOf(String fieldReference) {
+ public ReplaceAll findValueOf(String fieldReference) {
Assert.notNull(fieldReference, "fieldReference must not be null!");
@@ -2339,7 +2411,7 @@ public class StringOperators {
* @param expression must not be {@literal null}.
* @return new instance of {@link ReplaceAll}.
*/
- public ReplaceAll findOf(AggregationExpression expression) {
+ public ReplaceAll findValueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
index f8bfdf121..e308124eb 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
@@ -865,17 +865,17 @@ public class SpelExpressionTransformerUnitTests {
.isEqualTo("{ \"$regexMatch\" : {\"input\" : \"$field1\" , \"regex\" : \"e\" , \"options\" : \"$field2\"}}");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceOne() {
- assertThat(transform("replaceOne(field,'bar','baz')"))
+ assertThat(transform("replaceOne(field, 'bar', 'baz')"))
.isEqualTo("{ \"$replaceOne\" : {\"input\" : \"$field\" , \"find\" : \"bar\" , \"replacement\" : \"baz\"}}");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceAll() {
- assertThat(transform("replaceAll(field,'bar','baz')"))
+ assertThat(transform("replaceAll(field, 'bar', 'baz')"))
.isEqualTo("{ \"$replaceAll\" : {\"input\" : \"$field\" , \"find\" : \"bar\" , \"replacement\" : \"baz\"}}");
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java
index 35f9611fc..79897f61a 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java
@@ -282,34 +282,31 @@ class StringOperatorsUnitTests {
+ " } } ");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceOne() {
assertThat(StringOperators.valueOf("bar").replaceOne("foobar","baz").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $replaceOne : {\"find\" : \"foobar\", \"input\" : \"$bar\", \"replacement\" : \"baz\"}}");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceOneForExpression() {
assertThat(StringOperators.valueOf(EXPRESSION).replaceOne("a","s").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $replaceOne : {\"find\" : \"a\", \"input\" : " + EXPRESSION_STRING + ", \"replacement\" : \"s\"}}");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceAll() {
assertThat(StringOperators.valueOf("bar").replaceAll("foobar","baz").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $replaceAll : {\"find\" : \"foobar\", \"input\" : \"$bar\", \"replacement\" : \"baz\"}}");
}
- @Test
+ @Test // GH-3695
void shouldRenderReplaceAllForExpression() {
assertThat(StringOperators.valueOf(EXPRESSION).replaceAll("a","s").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $replaceAll : {\"find\" : \"a\", \"input\" : " + EXPRESSION_STRING + ", \"replacement\" : \"s\"}}");
}
-
-
-
}
diff --git a/src/main/asciidoc/reference/aggregation-framework.adoc b/src/main/asciidoc/reference/aggregation-framework.adoc
index fe3155848..c5db5f30a 100644
--- a/src/main/asciidoc/reference/aggregation-framework.adoc
+++ b/src/main/asciidoc/reference/aggregation-framework.adoc
@@ -88,7 +88,7 @@ At the time of this writing, we provide support for the following Aggregation Op
| `abs`, `acos`, `acosh`, `add` (+++*+++ via `plus`), `asin`, `asin`, `atan`, `atan2`, `atanh`, `ceil`, `cos`, `cosh`, `derivative`, `divide`, `exp`, `floor`, `integral`, `ln`, `log`, `log10`, `mod`, `multiply`, `pow`, `round`, `sqrt`, `subtract` (+++*+++ via `minus`), `sin`, `sinh`, `tan`, `tanh`, `trunc`
| String Aggregation Operators
-| `concat`, `substr`, `toLower`, `toUpper`, `strcasecmp`, `indexOfBytes`, `indexOfCP`, `regexFind`, `regexFindAll`, `regexMatch`, `split`, `strLenBytes`, `strLenCP`, `substrCP`, `trim`, `ltrim`, `rtim`
+| `concat`, `substr`, `toLower`, `toUpper`, `strcasecmp`, `indexOfBytes`, `indexOfCP`, `regexFind`, `regexFindAll`, `regexMatch`, `replaceAll`, `replaceOne`, split`, `strLenBytes`, `strLenCP`, `substrCP`, `trim`, `ltrim`, `rtim`
| Comparison Aggregation Operators
| `eq` (+++*+++ via `is`), `gt`, `gte`, `lt`, `lte`, `ne`