Browse Source

DATAMONGO-2049 - Add support for $ltrim, $rtrim, and $trim.

Original pull request: #594.
pull/599/merge
Christoph Strobl 7 years ago committed by Mark Paluch
parent
commit
9764ce0147
  1. 382
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java
  2. 146
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java
  3. 2
      src/main/asciidoc/reference/mongodb.adoc

382
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/StringOperators.java

@ -350,8 +350,7 @@ public class StringOperators { @@ -350,8 +350,7 @@ public class StringOperators {
* @return
*/
public StrLenBytes length() {
return usesFieldRef() ? StrLenBytes.stringLengthOf(fieldReference)
: StrLenBytes.stringLengthOf(expression);
return usesFieldRef() ? StrLenBytes.stringLengthOf(fieldReference) : StrLenBytes.stringLengthOf(expression);
}
/**
@ -391,6 +390,132 @@ public class StringOperators { @@ -391,6 +390,132 @@ public class StringOperators {
return usesFieldRef() ? SubstrCP.valueOf(fieldReference) : SubstrCP.valueOf(expression);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims whitespaces
* from the beginning and end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @return new instance of {@link Trim}.
* @since 2.1
*/
public Trim trim() {
return createTrim();
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the given
* character sequence from the beginning and end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link Trim}.
* @since 2.1
*/
public Trim trim(String chars) {
return trim().chars(chars);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the character
* sequence resulting from the given {@link AggregationExpression} from the beginning and end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link Trim}.
* @since 2.1
*/
public Trim trim(AggregationExpression expression) {
return trim().charsOf(expression);
}
private Trim createTrim() {
return usesFieldRef() ? Trim.valueOf(fieldReference) : Trim.valueOf(expression);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims whitespaces
* from the beginning. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @return new instance of {@link LTrim}.
* @since 2.1
*/
public LTrim ltrim() {
return createLTrim();
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the given
* character sequence from the beginning. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link LTrim}.
* @since 2.1
*/
public LTrim ltrim(String chars) {
return ltrim().chars(chars);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the character
* sequence resulting from the given {@link AggregationExpression} from the beginning. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link LTrim}.
* @since 2.1
*/
public LTrim ltrim(AggregationExpression expression) {
return ltrim().charsOf(expression);
}
private LTrim createLTrim() {
return usesFieldRef() ? LTrim.valueOf(fieldReference) : LTrim.valueOf(expression);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims whitespaces
* from the end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @return new instance of {@link RTrim}.
* @since 2.1
*/
public RTrim rtrim() {
return createRTrim();
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the given
* character sequence from the end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link RTrim}.
* @since 2.1
*/
public RTrim rtrim(String chars) {
return rtrim().chars(chars);
}
/**
* Creates new {@link AggregationExpression} that takes the associated string representation and trims the character
* sequence resulting from the given {@link AggregationExpression} from the end. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link RTrim}.
* @since 2.1
*/
public RTrim rtrim(AggregationExpression expression) {
return rtrim().charsOf(expression);
}
private RTrim createRTrim() {
return usesFieldRef() ? RTrim.valueOf(fieldReference) : RTrim.valueOf(expression);
}
private boolean usesFieldRef() {
return fieldReference != null;
}
@ -1072,4 +1197,257 @@ public class StringOperators { @@ -1072,4 +1197,257 @@ public class StringOperators {
return new SubstrCP(append(Arrays.asList(start, nrOfChars)));
}
}
/**
* {@link AggregationExpression} for {@code $trim} which removes whitespace or the specified characters from the
* beginning and end of a string. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @author Christoph Strobl
* @since 2.1
*/
public static class Trim extends AbstractAggregationExpression {
private Trim(Object value) {
super(value);
}
/**
* Creates new {@link Trim} using the value of the provided {@link Field fieldReference} as {@literal input} value.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public static Trim valueOf(String fieldReference) {
Assert.notNull(fieldReference, "FieldReference must not be null!");
return new Trim(Collections.singletonMap("input", Fields.field(fieldReference)));
}
/**
* Creates new {@link Trim} using the result of the provided {@link AggregationExpression} as {@literal input}
* value.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link Trim}.
*/
public static Trim valueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
return new Trim(Collections.singletonMap("input", expression));
}
/**
* Optional specify the character(s) to trim from the beginning.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link Trim}.
*/
public Trim chars(String chars) {
Assert.notNull(chars, "Chars must not be null!");
return new Trim(append("chars", chars));
}
/**
* Optional specify the reference to the {@link Field field} holding the character values to trim from the
* beginning.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link Trim}.
*/
public Trim charsOf(String fieldReference) {
return new Trim(append("chars", Fields.field(fieldReference)));
}
/**
* Optional specify the {@link AggregationExpression} evaluating to the character sequence to trim from the
* beginning.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link Trim}.
*/
public Trim charsOf(AggregationExpression expression) {
return new Trim(append("chars", expression));
}
/**
* Remove whitespace or the specified characters from the beginning of a string.<br />
*
* @return new instance of {@link LTrim}.
*/
public LTrim left() {
return new LTrim(argumentMap());
}
/**
* Remove whitespace or the specified characters from the end of a string.<br />
*
* @return new instance of {@link RTrim}.
*/
public RTrim right() {
return new RTrim(argumentMap());
}
@Override
protected String getMongoMethod() {
return "$trim";
}
}
/**
* {@link AggregationExpression} for {@code $ltrim} which removes whitespace or the specified characters from the
* beginning of a string. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @author Christoph Strobl
* @since 2.1
*/
public static class LTrim extends AbstractAggregationExpression {
private LTrim(Object value) {
super(value);
}
/**
* Creates new {@link LTrim} using the value of the provided {@link Field fieldReference} as {@literal input} value.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public static LTrim valueOf(String fieldReference) {
Assert.notNull(fieldReference, "FieldReference must not be null!");
return new LTrim(Collections.singletonMap("input", Fields.field(fieldReference)));
}
/**
* Creates new {@link LTrim} using the result of the provided {@link AggregationExpression} as {@literal input}
* value.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public static LTrim valueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
return new LTrim(Collections.singletonMap("input", expression));
}
/**
* Optional specify the character(s) to trim from the beginning.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public LTrim chars(String chars) {
Assert.notNull(chars, "Chars must not be null!");
return new LTrim(append("chars", chars));
}
/**
* Optional specify the reference to the {@link Field field} holding the character values to trim from the
* beginning.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public LTrim charsOf(String fieldReference) {
return new LTrim(append("chars", Fields.field(fieldReference)));
}
/**
* Optional specify the {@link AggregationExpression} evaluating to the character sequence to trim from the
* beginning.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link LTrim}.
*/
public LTrim charsOf(AggregationExpression expression) {
return new LTrim(append("chars", expression));
}
@Override
protected String getMongoMethod() {
return "$ltrim";
}
}
/**
* {@link AggregationExpression} for {@code $rtrim} which removes whitespace or the specified characters from the end
* of a string. <br />
* <strong>NOTE:</strong> Requires MongoDB 4.0 or later.
*
* @author Christoph Strobl
* @since 2.1
*/
public static class RTrim extends AbstractAggregationExpression {
private RTrim(Object value) {
super(value);
}
/**
* Creates new {@link RTrim} using the value of the provided {@link Field fieldReference} as {@literal input} value.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link RTrim}.
*/
public static RTrim valueOf(String fieldReference) {
Assert.notNull(fieldReference, "FieldReference must not be null!");
return new RTrim(Collections.singletonMap("input", Fields.field(fieldReference)));
}
/**
* Creates new {@link RTrim} using the result of the provided {@link AggregationExpression} as {@literal input}
* value.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link RTrim}.
*/
public static RTrim valueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
return new RTrim(Collections.singletonMap("input", expression));
}
/**
* Optional specify the character(s) to trim from the end.
*
* @param chars must not be {@literal null}.
* @return new instance of {@link RTrim}.
*/
public RTrim chars(String chars) {
Assert.notNull(chars, "Chars must not be null!");
return new RTrim(append("chars", chars));
}
/**
* Optional specify the reference to the {@link Field field} holding the character values to trim from the end.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link RTrim}.
*/
public RTrim charsOf(String fieldReference) {
return new RTrim(append("chars", Fields.field(fieldReference)));
}
/**
* Optional specify the {@link AggregationExpression} evaluating to the character sequence to trim from the end.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link RTrim}.
*/
public RTrim charsOf(AggregationExpression expression) {
return new RTrim(append("chars", expression));
}
@Override
protected String getMongoMethod() {
return "$rtrim";
}
}
}

146
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/StringOperatorsUnitTests.java

@ -0,0 +1,146 @@ @@ -0,0 +1,146 @@
/*
* Copyright 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.mongodb.core.aggregation;
import org.assertj.core.api.Assertions;
import org.bson.Document;
import org.junit.Test;
/**
* Unit test for {@link StringOperators}.
*
* @author Christoph Strobl
* @currentRead Royal Assassin - Robin Hobb
*/
public class StringOperatorsUnitTests {
static final String EXPRESSION_STRING = "{ \"$fitz\" : \"chivalry\" }";
static final Document EXPRESSION_DOC = Document.parse(EXPRESSION_STRING);
static final AggregationExpression EXPRESSION = context -> EXPRESSION_DOC;
@Test // DATAMONGO-2049
public void shouldRenderTrim() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $trim: { \"input\" : \"$shrewd\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimForExpression() {
Assertions.assertThat(StringOperators.valueOf(EXPRESSION).trim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $trim: { \"input\" : " + EXPRESSION_STRING + " } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimWithChars() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim("sh").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $trim: { \"input\" : \"$shrewd\", \"chars\" : \"sh\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimWithCharsExpression() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim(EXPRESSION).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $trim: { \"input\" : \"$shrewd\", \"chars\" : " + EXPRESSION_STRING + " } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimLeft() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim().left().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : \"$shrewd\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimLeftWithChars() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim("sh").left().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : \"$shrewd\", \"chars\" : \"sh\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimRight() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim().right().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : \"$shrewd\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderTrimRightWithChars() {
Assertions.assertThat(StringOperators.valueOf("shrewd").trim("sh").right().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : \"$shrewd\", \"chars\" : \"sh\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderLTrim() {
Assertions.assertThat(StringOperators.valueOf("shrewd").ltrim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : \"$shrewd\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderLTrimForExpression() {
Assertions.assertThat(StringOperators.valueOf(EXPRESSION).ltrim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : " + EXPRESSION_STRING + " } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderLTrimWithChars() {
Assertions.assertThat(StringOperators.valueOf("shrewd").ltrim("sh").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : \"$shrewd\", \"chars\" : \"sh\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderLTrimWithCharsExpression() {
Assertions.assertThat(StringOperators.valueOf("shrewd").ltrim(EXPRESSION).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $ltrim: { \"input\" : \"$shrewd\", \"chars\" : " + EXPRESSION_STRING + " } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderRTrim() {
Assertions.assertThat(StringOperators.valueOf("shrewd").rtrim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : \"$shrewd\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderRTrimForExpression() {
Assertions.assertThat(StringOperators.valueOf(EXPRESSION).rtrim().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : " + EXPRESSION_STRING + " } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderRTrimWithChars() {
Assertions.assertThat(StringOperators.valueOf("shrewd").rtrim("sh").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : \"$shrewd\", \"chars\" : \"sh\" } } "));
}
@Test // DATAMONGO-2049
public void shouldRenderRTrimWithCharsExpression() {
Assertions.assertThat(StringOperators.valueOf("shrewd").rtrim(EXPRESSION).toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $rtrim: { \"input\" : \"$shrewd\", \"chars\" : " + EXPRESSION_STRING + " } } "));
}
}

2
src/main/asciidoc/reference/mongodb.adoc

@ -2119,7 +2119,7 @@ At the time of this writing, we provide support for the following Aggregation Op @@ -2119,7 +2119,7 @@ At the time of this writing, we provide support for the following Aggregation Op
| `abs`, `add` (*via `plus`), `ceil`, `divide`, `exp`, `floor`, `ln`, `log`, `log10`, `mod`, `multiply`, `pow`, `sqrt`, `subtract` (*via `minus`), `trunc`
| String Aggregation Operators
| `concat`, `substr`, `toLower`, `toUpper`, `stcasecmp`, `indexOfBytes`, `indexOfCP`, `split`, `strLenBytes`, `strLenCP`, `substrCP`
| `concat`, `substr`, `toLower`, `toUpper`, `stcasecmp`, `indexOfBytes`, `indexOfCP`, `split`, `strLenBytes`, `strLenCP`, `substrCP`, `trim`, `ltrim`, `rtim`
| Comparison Aggregation Operators
| `eq` (*via: `is`), `gt`, `gte`, `lt`, `lte`, `ne`

Loading…
Cancel
Save