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`