From d151e2f66855d9f6bd24c36f7db32a2d8a3b60ed Mon Sep 17 00:00:00 2001 From: divyajnu08 Date: Sun, 29 Aug 2021 16:41:52 +0530 Subject: [PATCH 1/3] Allow $stdDevPop & stdDevSamp operators to be used in $project, $addFields, $set, ... aggregation stages. --- .../core/aggregation/AddFieldsOperation.java | 43 +++++++- .../mongodb/core/aggregation/Aggregation.java | 12 ++- .../core/aggregation/EvaluationOperators.java | 101 ++++++++++++++++++ .../core/aggregation/MatchOperation.java | 36 ++++++- .../core/aggregation/ProjectionOperation.java | 18 ++++ .../aggregation/ReplaceRootOperation.java | 21 +++- .../aggregation/ReplaceWithOperation.java | 17 +++ .../core/aggregation/SetOperation.java | 27 +++++ .../aggregation/SetWindowFieldsOperation.java | 16 +++ .../AddFieldsOperationUnitTests.java | 16 +++ .../aggregation/AggregationUnitTests.java | 24 +++++ .../aggregation/MatchOperationUnitTests.java | 26 +++++ .../ProjectionOperationUnitTests.java | 18 ++++ .../ReplaceRootOperationUnitTests.java | 18 +++- .../ReplaceWithOperationUnitTests.java | 17 +++ .../aggregation/SetOperationUnitTests.java | 17 +++ .../SetWindowFieldsOperationUnitTests.java | 28 +++++ 17 files changed, 449 insertions(+), 6 deletions(-) create mode 100644 spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java create mode 100644 spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index 3f3dd125d1..9f52a59d54 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -19,7 +19,13 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.bson.Document; import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder.ValueAppender; +import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; +import org.springframework.data.mongodb.core.aggregation.GroupOperation.Keyword; +import org.springframework.data.mongodb.core.aggregation.GroupOperation.Operation; +import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder; + import org.springframework.lang.Nullable; /** @@ -123,7 +129,7 @@ private AddFieldsOperationBuilder() { private AddFieldsOperationBuilder(Map source) { this.valueMap = new LinkedHashMap<>(source); } - + public AddFieldsOperationBuilder addFieldWithValue(String field, @Nullable Object value) { return addField(field).withValue(value); } @@ -131,6 +137,8 @@ public AddFieldsOperationBuilder addFieldWithValue(String field, @Nullable Objec public AddFieldsOperationBuilder addFieldWithValueOf(String field, Object value) { return addField(field).withValueOf(value); } + + /** * Define the field to add. @@ -162,13 +170,30 @@ public AddFieldsOperationBuilder withValueOfExpression(String operation, Object. valueMap.put(field, new ExpressionProjection(operation, values)); return AddFieldsOperationBuilder.this; } + + public AddFieldsOperationBuilder stdDevPop(String fieldRef) { + return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); + } + + public AddFieldsOperationBuilder stdDevPop(AggregationExpression expression) { + return withValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); + } + + public AddFieldsOperationBuilder stdDevSamp(String fieldRef) { + return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); + } + + public AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression) { + return withValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); + } + }; } public AddFieldsOperation build() { return new AddFieldsOperation(valueMap); } - + /** * @author Christoph Strobl * @since 3.0 @@ -199,6 +224,20 @@ public interface ValueAppender { * @return new instance of {@link AddFieldsOperation}. */ AddFieldsOperationBuilder withValueOfExpression(String operation, Object... values); + + AddFieldsOperationBuilder stdDevPop(String fieldRef); + + AddFieldsOperationBuilder stdDevPop(AggregationExpression expression); + + AddFieldsOperationBuilder stdDevSamp(String fieldRef); + + AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression); + + } + + } + + } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java index cecc8f2554..55964bab93 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java @@ -498,7 +498,17 @@ public static MatchOperation match(Criteria criteria) { public static MatchOperation match(CriteriaDefinition criteria) { return new MatchOperation(criteria); } - + + /** + * Creates a new {@link MatchOperation} + * + * @return new instance of {@link MatchOperation}. + * @since 1.10 + */ + public static MatchOperation match() { + return new MatchOperation(); + } + /** * Creates a new {@link GeoNearOperation} instance from the given {@link NearQuery} and the {@code distanceField}. The * {@code distanceField} defines output field that contains the calculated distance. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java new file mode 100644 index 0000000000..da9b9df679 --- /dev/null +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java @@ -0,0 +1,101 @@ +package org.springframework.data.mongodb.core.aggregation; + +import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.Abs; +import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.ArithmeticOperatorFactory; +import org.springframework.util.Assert; + +public class EvaluationOperators { + + /** + * Take the value resulting from the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + * @return new instance of {@link ArithmeticOperatorFactory}. + */ + public static EvaluationOperatorFactory valueOf(AggregationExpression expression) { + return new EvaluationOperatorFactory(expression); + } + + public static class EvaluationOperatorFactory { + + private final String fieldReference; + private final AggregationExpression expression; + + /** + * Creates new {@link EvaluationOperatorFactory} for given {@literal fieldReference}. + * + * @param fieldReference must not be {@literal null}. + */ + public EvaluationOperatorFactory(String fieldReference) { + + Assert.notNull(fieldReference, "FieldReference must not be null!"); + this.fieldReference = fieldReference; + this.expression = null; + } + + + /** + * Creates new {@link EvaluationOperatorFactory} for given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + */ + public EvaluationOperatorFactory(AggregationExpression expression) { + + Assert.notNull(expression, "Expression must not be null!"); + this.fieldReference = null; + this.expression = expression; + } + + /** + * Creates new {@link AggregationExpression} that returns the absolute value of the associated number. + * + * @return new instance of {@link Expr}. + */ + public Expr expr() { + return usesFieldRef() ? Expr.valueOf(fieldReference) : Expr.valueOf(expression); + } + + + public static class Expr extends AbstractAggregationExpression { + + private Expr(Object value) { + super(value); + } + + @Override + protected String getMongoMethod() { + return "$expr"; + } + + /** + * Creates new {@link Expr}. + * + * @param fieldReference must not be {@literal null}. + * @return new instance of {@link Expr}. + */ + public static Expr valueOf(String fieldReference) { + + Assert.notNull(fieldReference, "FieldReference must not be null!"); + return new Expr(Fields.field(fieldReference)); + } + + /** + * Creates new {@link Abs}. + * + * @param expression must not be {@literal null}. + * @return new instance of {@link Abs}. + */ + public static Expr valueOf(AggregationExpression expression) { + + Assert.notNull(expression, "Expression must not be null!"); + return new Expr(expression); + } + + } + + private boolean usesFieldRef() { + return fieldReference != null; + } + } + +} diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java index c9d83ae6c8..dfc17d74c7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java @@ -36,7 +36,12 @@ public class MatchOperation implements AggregationOperation { private final CriteriaDefinition criteriaDefinition; - + private final AggregationExpression expression; + + public MatchOperation() { + this.criteriaDefinition = null; + this.expression = null; + } /** * Creates a new {@link MatchOperation} for the given {@link CriteriaDefinition}. * @@ -46,7 +51,17 @@ public MatchOperation(CriteriaDefinition criteriaDefinition) { Assert.notNull(criteriaDefinition, "Criteria must not be null!"); this.criteriaDefinition = criteriaDefinition; + this.expression = null; } + + private MatchOperation(AggregationExpression expression) { + + Assert.notNull(expression, "Expression must not be null!"); + this.criteriaDefinition = null; + this.expression = expression; + } + + /* * (non-Javadoc) @@ -54,6 +69,9 @@ public MatchOperation(CriteriaDefinition criteriaDefinition) { */ @Override public Document toDocument(AggregationOperationContext context) { + if(expression != null) { + return new Document(getOperator(), expression.toDocument()); + } return new Document(getOperator(), context.getMappedObject(criteriaDefinition.getCriteriaObject())); } @@ -65,4 +83,20 @@ public Document toDocument(AggregationOperationContext context) { public String getOperator() { return "$match"; } + + public MatchOperation stdDevPop(String fieldReference) { + return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevPop()).expr()); + } + + public MatchOperation stdDevPop(AggregationExpression expression) { + return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevPop()).expr()); + } + + public MatchOperation stdDevSamp(String fieldReference) { + return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()).expr()); + } + + public MatchOperation stdDevSamp(AggregationExpression expression) { + return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()).expr()); + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index d2f173e90b..c2468d159c 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -1306,6 +1306,24 @@ public ProjectionOperationBuilder let(AggregationExpression valueExpression, Str public ProjectionOperationBuilder let(Collection variables, AggregationExpression in) { return this.operation.and(VariableOperators.Let.define(variables).andApply(in)); } + + /** + * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field + * + * @return + */ + public ProjectionOperationBuilder stdDevPop() { + return this.operation.and(AccumulatorOperators.StdDevPop.stdDevPopOf(getRequiredName())); + } + + /** + * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field + * + * @return + */ + public ProjectionOperationBuilder stdDevSamp() { + return this.operation.and(AccumulatorOperators.StdDevSamp.stdDevSampOf(getRequiredName())); + } private String getRequiredName() { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index c452ffb8ea..9e6aeacdc9 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -21,6 +21,7 @@ import java.util.List; import org.bson.Document; +import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder; import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField; import org.springframework.expression.spel.ast.Projection; import org.springframework.util.Assert; @@ -112,7 +113,8 @@ public ExposedFields getFields() { protected Replacement getReplacement() { return replacement; } - + + /** * Builder for {@link ReplaceRootOperation}. * @@ -165,6 +167,23 @@ public ReplaceRootOperation withDocument(Document document) { return new ReplaceRootDocumentOperation().andValuesOf(document); } + + public ReplaceRootOperation stdDevPop(String fieldRef) { + return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); + } + + public ReplaceRootOperation stdDevPop(AggregationExpression expression) { + return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevPop()); + } + + public ReplaceRootOperation stdDevSamp(String fieldRef) { + return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); + } + + public ReplaceRootOperation stdDevSamp(AggregationExpression expression) { + return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevSamp()); + } + } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java index 0d53dbf5cf..2323770d66 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java @@ -92,4 +92,21 @@ private static Object computeValue(Object value, AggregationOperationContext con public Document toDocument(AggregationOperationContext context) { return context.getMappedObject(new Document("$replaceWith", getReplacement().toDocumentExpression(context))); } + + + public static ReplaceWithOperation stdDevPop(String fieldRef) { + return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); + } + + public static ReplaceWithOperation stdDevPop(AggregationExpression expression) { + return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); + } + + public static ReplaceWithOperation stdDevSamp(String fieldRef) { + return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); + } + + public static ReplaceWithOperation stdDevSamp(AggregationExpression expression) { + return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index 731668ed3c..ed6fd13133 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -19,6 +19,7 @@ import java.util.LinkedHashMap; import java.util.Map; +import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation.AddFieldsOperationBuilder; import org.springframework.data.mongodb.core.aggregation.SetOperation.FieldAppender.ValueAppender; import org.springframework.lang.Nullable; @@ -154,6 +155,22 @@ public SetOperation withValueOfExpression(String operation, Object... values) { valueMap.put(field, new ExpressionProjection(operation, values)); return FieldAppender.this.build(); } + + public SetOperation stdDevPop(String fieldRef) { + return toValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); + } + + public SetOperation stdDevPop(AggregationExpression expression) { + return toValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); + } + + public SetOperation stdDevSamp(String fieldRef) { + return toValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); + } + + public SetOperation stdDevSamp(AggregationExpression expression) { + return toValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); + } }; } @@ -192,6 +209,16 @@ public interface ValueAppender { * @return new instance of {@link SetOperation}. */ SetOperation withValueOfExpression(String operation, Object... values); + + SetOperation stdDevPop(String fieldRef); + + SetOperation stdDevPop(AggregationExpression expression); + + SetOperation stdDevSamp(String fieldRef); + + SetOperation stdDevSamp(AggregationExpression expression); } + + } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index 9c40a0b642..54fe58f770 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -755,6 +755,22 @@ public SetWindowFieldsOperationBuilder as(String targetFieldName) { } }; } + + public WindowChoice stdDevPop(String fieldReference) { + return output(AccumulatorOperators.valueOf(fieldReference).stdDevPop()); + } + + public WindowChoice stdDevPop(AggregationExpression expression) { + return output(AccumulatorOperators.valueOf(expression).stdDevPop()); + } + + public WindowChoice stdDevSamp(String fieldReference) { + return output(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()); + } + + public WindowChoice stdDevSamp(AggregationExpression expression) { + return output(AccumulatorOperators.valueOf(expression).stdDevSamp()); + } /** * Interface to capture field name used to capture the computation result. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java index b2f2bd611d..d7a83a246c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java @@ -126,6 +126,22 @@ void exposesFieldsCorrectly() { assertThat(fields.getField("computed")).isNotNull(); assertThat(fields.getField("does-not-exist")).isNull(); } + + @Test + void rendersStdDevPopCorrectly() { + assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevPop("quiz").build() + .toPipelineStages(contextFor(ScoresWrapper.class))) + .containsExactly(Document.parse( + "{\"$addFields\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); + } + + @Test + void rendersStdDevSampCorrectly() { + assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevSamp("quiz").build() + .toPipelineStages(contextFor(ScoresWrapper.class))) + .containsExactly(Document.parse( + "{\"$addFields\" : {\"totalQuiz\": { \"$stdDevSamp\" : \"$quiz\" } }}")); + } private static AggregationOperationContext contextFor(@Nullable Class type) { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java index 37aeb5b2cf..ad5b3b7f2e 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java @@ -133,6 +133,30 @@ void unwindOperationWithPreserveNullShouldBuildCorrectClause() { .doesNotContainKey("$unwind.includeArrayIndex") // .containsEntry("$unwind.preserveNullAndEmptyArrays", true); } + + @Test + void addFieldsOperationWithStdDevPopShouldBuildCorrectly() { + Document agg = newAggregation( // + addFields().addField("totalQuiz").stdDevPop("quiz").build()) // + .toDocument("foo",Aggregation.DEFAULT_CONTEXT); + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$addFields\" : { \"totalQuiz\" : { \"$stdDevPop\" : \"$quiz\" }}}")); + } + + @Test + void addFieldsOperationWithStdDevSampShouldBuildCorrectly() { + Document agg = newAggregation( // + addFields().addField("totalQuiz").stdDevSamp("quiz").build()) // + .toDocument("foo",Aggregation.DEFAULT_CONTEXT); + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$addFields\" : { \"totalQuiz\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); + } + + @Test // DATAMONGO-1550 void replaceRootOperationShouldBuildCorrectClause() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java new file mode 100644 index 0000000000..f760bd6db7 --- /dev/null +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java @@ -0,0 +1,26 @@ +package org.springframework.data.mongodb.core.aggregation; + +import static org.assertj.core.api.Assertions.*; + +import org.bson.Document; +import org.junit.jupiter.api.Test; + +class MatchOperationUnitTests { + + @Test + public void shouldRenderStdDevPopCorrectly() { + MatchOperation operation = Aggregation.match().stdDevPop("size"); + assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). + isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevPop\" : \"$size\" } } } ")); + + } + + @Test + public void shouldRenderStdDevSampCorrectly() { + MatchOperation operation = Aggregation.match().stdDevSamp("size"); + assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). + isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevSamp\" : \"$size\" } } } ")); + + } + +} diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java index 805fc10f38..7b8e12115a 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java @@ -1463,6 +1463,24 @@ public void shouldRenderMinWithMultipleArgsAggregationExpression() { assertThat(agg).isEqualTo(Document.parse("{ $project: { examMin: { $min: [ \"$final\", \"$midterm\" ] } } }")); } + @Test // DATAMONGO- + public void shouldRenderStdDevPopExpressionCorrectly() { + + Document agg = new ProjectionOperation().and("scores").stdDevPop().as("stdDev") + .toDocument(Aggregation.DEFAULT_CONTEXT); + + assertThat(agg).isEqualTo(Document.parse("{ $project: { stdDev: { $stdDevPop: \"$scores\"} } }")); + } + + @Test // DATAMONGO- + public void shouldRenderStdSampExpressionCorrectly() { + + Document agg = new ProjectionOperation().and("scores").stdDevSamp().as("stdDev") + .toDocument(Aggregation.DEFAULT_CONTEXT); + + assertThat(agg).isEqualTo(Document.parse("{ $project: { stdDev: { $stdDevSamp: \"$scores\"} } }")); + } + @Test // DATAMONGO-1536 public void shouldRenderStdDevPopAggregationExpression() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java index e97e1ff018..ffe559e9f3 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java @@ -19,7 +19,7 @@ import org.bson.Document; import org.junit.jupiter.api.Test; - +import org.springframework.data.mongodb.core.aggregation.AddFieldsOperationUnitTests.ScoresWrapper; import org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.ReplaceRootDocumentOperation; /** @@ -99,4 +99,20 @@ public void shouldNotExposeFields() { assertThat(operation.getFields().exposesNoFields()).isTrue(); assertThat(operation.getFields().exposesSingleFieldOnly()).isFalse(); } + + @Test + void shouldRendersStdDevPopCorrectly() { + ReplaceRootOperation operation = ReplaceRootDocumentOperation.builder().stdDevPop("quiz"); + Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); + assertThat(dbObject).isEqualTo(Document.parse( + "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevPop\" : \"$quiz\" } }}")); + } + + @Test + void shouldRendersStdDevSampCorrectly() { + ReplaceRootOperation operation = ReplaceRootDocumentOperation.builder().stdDevSamp("quiz"); + Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); + assertThat(dbObject).isEqualTo(Document.parse( + "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevSamp\" : \"$quiz\" } }}")); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java index 8f8b5c9dd1..75bb3519c0 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java @@ -19,6 +19,7 @@ import org.bson.Document; import org.junit.jupiter.api.Test; +import org.springframework.data.mongodb.core.aggregation.ReplaceRootOperation.ReplaceRootDocumentOperation; /** * Unit tests for {@link ReplaceRootOperation}. @@ -54,4 +55,20 @@ public void shouldRenderExpressionCorrectly() { assertThat(dbObject).isEqualTo(Document.parse("{ $replaceWith : { " + "$map : { input : \"$array\" , as : \"element\" , in : { $multiply : [ \"$$element\" , 10]} } " + "} }")); } + + @Test + void shouldRendersStdDevPopCorrectly() { + ReplaceWithOperation operation = ReplaceWithOperation.stdDevPop("quiz"); + Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); + assertThat(dbObject).isEqualTo(Document.parse( + "{\"$replaceWith\" : { \"$stdDevPop\" : \"$quiz\" } }")); + } + + @Test + void shouldRendersStdDevSampCorrectly() { + ReplaceWithOperation operation = ReplaceWithOperation.stdDevSamp("quiz"); + Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); + assertThat(dbObject).isEqualTo(Document.parse( + "{\"$replaceWith\" : { \"$stdDevSamp\" : \"$quiz\" } }")); + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java index b90b049da1..085db0279a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java @@ -21,6 +21,7 @@ import org.bson.Document; import org.junit.jupiter.api.Test; +import org.springframework.data.mongodb.core.aggregation.AddFieldsOperationUnitTests.ScoresWrapper; import org.springframework.data.mongodb.core.convert.MappingMongoConverter; import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver; import org.springframework.data.mongodb.core.convert.QueryMapper; @@ -104,6 +105,22 @@ void rendersTargetValueExpressionCorrectly() { .toPipelineStages(contextFor(Scores.class))) .containsExactly(Document.parse("{\"$set\" : {\"totalHomework\": { \"$sum\" : \"$homework\" }}}")); } + + @Test + void rendersStdDevPopCorrectly() { + assertThat(SetOperation.builder().set("totalQuiz").stdDevPop("quiz") + .toPipelineStages(contextFor(ScoresWrapper.class))) + .containsExactly(Document.parse( + "{\"$set\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); + } + + @Test + void rendersStdDevSampCorrectly() { + assertThat(SetOperation.builder().set("totalQuiz").stdDevSamp("quiz") + .toPipelineStages(contextFor(ScoresWrapper.class))) + .containsExactly(Document.parse( + "{\"$set\" : {\"totalQuiz\": { \"$stdDevSamp\" : \"$quiz\" } }}")); + } @Test // DATAMONGO-2331 void exposesFieldsCorrectly() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java index 62b0f4dffc..8ca21de503 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java @@ -86,6 +86,34 @@ void rendersMuiltipleOutputFields() { assertThat(document).isEqualTo(Document.parse( "{ $setWindowFields: { output: { f1 : { $sum: \"$quantity\", window: { documents: [ \"unbounded\", \"current\" ] } }, f2 : { $avg: \"$quantity\", window: { documents: [ -1, 0 ] } } } } }")); } + + @Test // GH-3711 + void rendersOutputFieldsWithStdDevPopOperator() { + + SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // + .stdDevPop("qty") + .within(Windows.documents().fromUnbounded().toCurrent().build()) // + .as("f1") // + .build(); // + + Document document = setWindowFieldsOperation.toDocument(contextFor(CakeSale.class)); + assertThat(document).isEqualTo(Document.parse( + "{ $setWindowFields: { output: { f1 : { $stdDevPop: \"$quantity\", window: { documents: [ \"unbounded\", \"current\" ] } } } } }")); + } + + @Test // GH-3711 + void rendersOutputFieldsWithStdDevSampOperator() { + + SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // + .stdDevSamp("qty") + .within(Windows.documents().fromUnbounded().toCurrent().build()) // + .as("f1") // + .build(); // + + Document document = setWindowFieldsOperation.toDocument(contextFor(CakeSale.class)); + assertThat(document).isEqualTo(Document.parse( + "{ $setWindowFields: { output: { f1 : { $stdDevSamp: \"$quantity\", window: { documents: [ \"unbounded\", \"current\" ] } } } } }")); + } private static AggregationOperationContext contextFor(@Nullable Class type) { From 741fefbc54b66f0d87519e254b515d7dd15a3f91 Mon Sep 17 00:00:00 2001 From: divya srivastava Date: Sun, 29 Aug 2021 18:56:38 +0530 Subject: [PATCH 2/3] comments and unit tests. --- .../core/aggregation/AddFieldsOperation.java | 34 ++++++-- .../core/aggregation/EvaluationOperators.java | 8 +- .../core/aggregation/MatchOperation.java | 32 ++++++++ .../core/aggregation/ProjectionOperation.java | 4 +- .../aggregation/ReplaceRootOperation.java | 24 ++++++ .../aggregation/ReplaceWithOperation.java | 25 +++++- .../core/aggregation/SetOperation.java | 26 ++++++- .../aggregation/SetWindowFieldsOperation.java | 24 ++++++ .../AddFieldsOperationUnitTests.java | 4 +- .../aggregation/AggregationUnitTests.java | 78 ++++++++++++++++++- .../aggregation/MatchOperationUnitTests.java | 4 +- .../ReplaceRootOperationUnitTests.java | 8 +- .../ReplaceWithOperationUnitTests.java | 4 +- .../aggregation/SetOperationUnitTests.java | 4 +- .../SetWindowFieldsOperationUnitTests.java | 4 +- 15 files changed, 252 insertions(+), 31 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index 9f52a59d54..7fd8f51ea4 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -171,18 +171,22 @@ public AddFieldsOperationBuilder withValueOfExpression(String operation, Object. return AddFieldsOperationBuilder.this; } + @Override public AddFieldsOperationBuilder stdDevPop(String fieldRef) { return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); } + @Override public AddFieldsOperationBuilder stdDevPop(AggregationExpression expression) { return withValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); } + @Override public AddFieldsOperationBuilder stdDevSamp(String fieldRef) { return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); } + @Override public AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression) { return withValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); } @@ -225,18 +229,38 @@ public interface ValueAppender { */ AddFieldsOperationBuilder withValueOfExpression(String operation, Object... values); - AddFieldsOperationBuilder stdDevPop(String fieldRef); + /** + * Adds the field with the value of {@code $stdDevPop} of the given field reference. + * + * @param fieldRef must not be {@literal null}. + * @return new instance of {@link AddFieldsOperationBuilder}. + */ + AddFieldsOperationBuilder stdDevPop(String AddFieldsOperationBuilder); + /** + * Adds the field with the value of {@code $stdDevPop} of the given {@link AggregationExpression}.. + * + * @param fieldRef must not be {@literal null}. + * @return new instance of {@link AddFieldsOperationBuilder}. + */ AddFieldsOperationBuilder stdDevPop(AggregationExpression expression); + /** + * Adds the field with the value of {@code $stdDevSamp} of the given field reference. + * + * @param fieldRef must not be {@literal null}. + * @return new instance of {@link AddFieldsOperationBuilder}. + */ AddFieldsOperationBuilder stdDevSamp(String fieldRef); + /** + * Adds the field with the value of {@code $stdDevSamp} of the given {@link AggregationExpression}.. + * + * @param fieldRef must not be {@literal null}. + * @return new instance of {@link AddFieldsOperationBuilder}. + */ AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression); - - } - - } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java index da9b9df679..e7a25825d6 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java @@ -10,7 +10,7 @@ public class EvaluationOperators { * Take the value resulting from the given {@link AggregationExpression}. * * @param expression must not be {@literal null}. - * @return new instance of {@link ArithmeticOperatorFactory}. + * @return new instance of {@link EvaluationOperatorFactory}. */ public static EvaluationOperatorFactory valueOf(AggregationExpression expression) { return new EvaluationOperatorFactory(expression); @@ -47,7 +47,7 @@ public EvaluationOperatorFactory(AggregationExpression expression) { } /** - * Creates new {@link AggregationExpression} that returns the absolute value of the associated number. + * Creates new {@link AggregationExpression} that is a valid aggregation expression. * * @return new instance of {@link Expr}. */ @@ -80,10 +80,10 @@ public static Expr valueOf(String fieldReference) { } /** - * Creates new {@link Abs}. + * Creates new {@link Expr}. * * @param expression must not be {@literal null}. - * @return new instance of {@link Abs}. + * @return new instance of {@link Expr}. */ public static Expr valueOf(AggregationExpression expression) { diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java index dfc17d74c7..48e8d70769 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java @@ -38,6 +38,9 @@ public class MatchOperation implements AggregationOperation { private final CriteriaDefinition criteriaDefinition; private final AggregationExpression expression; + /** + * Creates a new {@link MatchOperation} + */ public MatchOperation() { this.criteriaDefinition = null; this.expression = null; @@ -54,6 +57,11 @@ public MatchOperation(CriteriaDefinition criteriaDefinition) { this.expression = null; } + /** + * Creates a new {@link MatchOperation} for the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + */ private MatchOperation(AggregationExpression expression) { Assert.notNull(expression, "Expression must not be null!"); @@ -84,18 +92,42 @@ public String getOperator() { return "$match"; } + /** + * Creates a new {@link MatchOperation} with the {@code stdDevPop} of the given fieldReference. + * + * @param fieldReference must not be {@literal null}. + * @return new instance of {@link MatchOperation} + */ public MatchOperation stdDevPop(String fieldReference) { return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevPop()).expr()); } + /** + * Creates a new {@link MatchOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + * @return new instance of {@link MatchOperation} + */ public MatchOperation stdDevPop(AggregationExpression expression) { return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevPop()).expr()); } + /** + * Creates a new {@link MatchOperation} with the {@code stdDevSamp} of the given fieldReference. + * + * @param fieldReference must not be {@literal null}. + * @return new instance of {@link MatchOperation} + */ public MatchOperation stdDevSamp(String fieldReference) { return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()).expr()); } + /** + * Creates a new {@link MatchOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + * @return new instance of {@link MatchOperation} + */ public MatchOperation stdDevSamp(AggregationExpression expression) { return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()).expr()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index c2468d159c..dcc8ef70c7 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -1310,7 +1310,7 @@ public ProjectionOperationBuilder let(Collection variables, /** * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field * - * @return + * @return never {@literal null}. */ public ProjectionOperationBuilder stdDevPop() { return this.operation.and(AccumulatorOperators.StdDevPop.stdDevPopOf(getRequiredName())); @@ -1319,7 +1319,7 @@ public ProjectionOperationBuilder stdDevPop() { /** * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field * - * @return + * @return never {@literal null}. */ public ProjectionOperationBuilder stdDevSamp() { return this.operation.and(AccumulatorOperators.StdDevSamp.stdDevSampOf(getRequiredName())); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index 9e6aeacdc9..4e6ab7874e 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -168,18 +168,42 @@ public ReplaceRootOperation withDocument(Document document) { return new ReplaceRootDocumentOperation().andValuesOf(document); } + /** + * Generates a new {@link ReplaceRootOperation} with the {@code stdDevPop} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link ReplaceRootOperation}. + */ public ReplaceRootOperation stdDevPop(String fieldRef) { return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); } + /** + * Generates a new {@link ReplaceRootOperation} with the {@code stdDevPop} of the given {@link AggregationExpression} + * + * @param expression must not be {@literal null} + * @return the final {@link ReplaceRootOperation}. + */ public ReplaceRootOperation stdDevPop(AggregationExpression expression) { return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevPop()); } + /** + * Generates a new {@link ReplaceRootOperation} with the {@code stdDevSamp} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link ReplaceRootOperation}. + */ public ReplaceRootOperation stdDevSamp(String fieldRef) { return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); } + /** + * Generates a new {@link ReplaceRootOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression} + * + * @param expression must not be {@literal null} + * @return the final {@link ReplaceRootOperation}. + */ public ReplaceRootOperation stdDevSamp(AggregationExpression expression) { return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevSamp()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java index 2323770d66..42524e09cb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java @@ -93,19 +93,42 @@ public Document toDocument(AggregationOperationContext context) { return context.getMappedObject(new Document("$replaceWith", getReplacement().toDocumentExpression(context))); } - + /** + * Generates a new {@link ReplaceWithOperation} with the {@code stdDevPop} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link ReplaceWithOperation}. + */ public static ReplaceWithOperation stdDevPop(String fieldRef) { return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); } + /** + * Generates a new {@link ReplaceWithOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link ReplaceWithOperation}. + */ public static ReplaceWithOperation stdDevPop(AggregationExpression expression) { return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); } + /** + * Generates a new {@link ReplaceWithOperation} with the {@code stdDevSamp} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link ReplaceWithOperation}. + */ public static ReplaceWithOperation stdDevSamp(String fieldRef) { return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); } + /** + * Generates a new {@link ReplaceWithOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link ReplaceWithOperation}. + */ public static ReplaceWithOperation stdDevSamp(AggregationExpression expression) { return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index ed6fd13133..e703d0e505 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -210,12 +210,36 @@ public interface ValueAppender { */ SetOperation withValueOfExpression(String operation, Object... values); + /** + * Generates a new {@link SetOperation} with the {@code stdDevPop} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link SetOperation}. + */ SetOperation stdDevPop(String fieldRef); + /** + * Generates a new {@link SetOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link SetOperation}. + */ SetOperation stdDevPop(AggregationExpression expression); + /** + * Generates a new {@link SetOperation} with the {@code stdDevSamp} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link SetOperation}. + */ SetOperation stdDevSamp(String fieldRef); - + + /** + * Generates a new {@link SetOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link SetOperation}. + */ SetOperation stdDevSamp(AggregationExpression expression); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index 54fe58f770..01d339f6fb 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -756,18 +756,42 @@ public SetWindowFieldsOperationBuilder as(String targetFieldName) { }; } + /** + * Generates a new {@link WindowChoice} with the {@code stdDevPop} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link WindowChoice}. + */ public WindowChoice stdDevPop(String fieldReference) { return output(AccumulatorOperators.valueOf(fieldReference).stdDevPop()); } + /** + * Generates a new {@link WindowChoice} with the {@code stdDevPop} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link WindowChoice}. + */ public WindowChoice stdDevPop(AggregationExpression expression) { return output(AccumulatorOperators.valueOf(expression).stdDevPop()); } + /** + * Generates a new {@link WindowChoice} with the {@code stdDevSamp} of the given field reference. + * + * @param fieldRef must not be {@literal null} + * @return the final {@link WindowChoice}. + */ public WindowChoice stdDevSamp(String fieldReference) { return output(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()); } + /** + * Generates a new {@link WindowChoice} with the {@code stdDevSamp} of the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null} + * @return the final {@link WindowChoice}. + */ public WindowChoice stdDevSamp(AggregationExpression expression) { return output(AccumulatorOperators.valueOf(expression).stdDevSamp()); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java index d7a83a246c..4a2375c788 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java @@ -127,7 +127,7 @@ void exposesFieldsCorrectly() { assertThat(fields.getField("does-not-exist")).isNull(); } - @Test + @Test // DATAMONGO - 3729 void rendersStdDevPopCorrectly() { assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevPop("quiz").build() .toPipelineStages(contextFor(ScoresWrapper.class))) @@ -135,7 +135,7 @@ void rendersStdDevPopCorrectly() { "{\"$addFields\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); } - @Test + @Test // DATAMONGO - 3729 void rendersStdDevSampCorrectly() { assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevSamp("quiz").build() .toPipelineStages(contextFor(ScoresWrapper.class))) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java index ad5b3b7f2e..1fe31d5bf7 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java @@ -134,7 +134,7 @@ void unwindOperationWithPreserveNullShouldBuildCorrectClause() { .containsEntry("$unwind.preserveNullAndEmptyArrays", true); } - @Test + @Test // DATAMONGO - 3729 void addFieldsOperationWithStdDevPopShouldBuildCorrectly() { Document agg = newAggregation( // addFields().addField("totalQuiz").stdDevPop("quiz").build()) // @@ -145,7 +145,7 @@ void addFieldsOperationWithStdDevPopShouldBuildCorrectly() { isEqualTo(Document.parse("{ \"$addFields\" : { \"totalQuiz\" : { \"$stdDevPop\" : \"$quiz\" }}}")); } - @Test + @Test // DATAMONGO - 3729 void addFieldsOperationWithStdDevSampShouldBuildCorrectly() { Document agg = newAggregation( // addFields().addField("totalQuiz").stdDevSamp("quiz").build()) // @@ -169,7 +169,31 @@ void replaceRootOperationShouldBuildCorrectClause() { Document unwind = ((List) agg.get("pipeline")).get(0); assertThat(unwind).containsEntry("$replaceRoot.newRoot", new Document("field", "value")); } - + + @Test // DATAMONGO - 3729 + void replaceRootOperationWithStdDevPopShouldBuildCorrectly() { + Document agg = newAggregation( + replaceRoot().stdDevPop("quiz")) + .toDocument("foo", Aggregation.DEFAULT_CONTEXT); + + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$replaceRoot\" : { \"newRoot\" : { \"$stdDevPop\" : \"$quiz\" }}}")); + } + + @Test // DATAMONGO - 3729 + void replaceRootOperationWithStdDevSampShouldBuildCorrectly() { + Document agg = newAggregation( + replaceRoot().stdDevSamp("quiz")) + .toDocument("foo", Aggregation.DEFAULT_CONTEXT); + + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$replaceRoot\" : { \"newRoot\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); + } + @Test // DATAMONGO-753 void matchOperationShouldNotChangeAvailableFields() { @@ -179,6 +203,28 @@ void matchOperationShouldNotChangeAvailableFields() { project("a", "b") // b should still be available ).toDocument("foo", Aggregation.DEFAULT_CONTEXT); } + + @Test // DATAMONGO - 3729 + void matchOperationWithStdDevPopShouldBuildCorrectly() { + Document agg = newAggregation( + match().stdDevPop("quiz")) + .toDocument("foo",Aggregation.DEFAULT_CONTEXT); + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$match\" : { \"$expr\" : { \"$stdDevPop\" : \"$quiz\" }}}")); + } + + @Test // DATAMONGO - 3729 + void matchOperationWithStdDevSampShouldBuildCorrectly() { + Document agg = newAggregation( + match().stdDevSamp("quiz")) + .toDocument("foo",Aggregation.DEFAULT_CONTEXT); + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$match\" : { \"$expr\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); + } @Test // DATAMONGO-788 void referencesToGroupIdsShouldBeRenderedAsReferences() { @@ -621,7 +667,31 @@ void projectOnIdIsAlwaysValid() { assertThat(extractPipelineElement(target, 1, "$project")).isEqualTo(Document.parse(" { \"_id\" : \"$_id\" }")); } - + + @Test // DATAMONGO - 3729 + void projectOperationWithStdDevPopShouldBuildCorrectly() { + Document agg = newAggregation( + project().and("quiz").stdDevPop().as("totalQuiz")) + .toDocument("foo", Aggregation.DEFAULT_CONTEXT); + + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$project\" : { \"totalQuiz\" : { \"$stdDevPop\" : \"$quiz\" }}}")); + } + + @Test // DATAMONGO - 3729 + void projectOperationWithStdDevSampShouldBuildCorrectly() { + Document agg = newAggregation( + project().and("quiz").stdDevSamp().as("totalQuiz")) + .toDocument("foo", Aggregation.DEFAULT_CONTEXT); + + @SuppressWarnings("unchecked") + Document addField = ((List) agg.get("pipeline")).get(0); + assertThat(addField). + isEqualTo(Document.parse("{ \"$project\" : { \"totalQuiz\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); + } + private Document extractPipelineElement(Document agg, int index, String operation) { List pipeline = (List) agg.get("pipeline"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java index f760bd6db7..af3595747a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java @@ -7,7 +7,7 @@ class MatchOperationUnitTests { - @Test + @Test // DATAMONGO - 3729 public void shouldRenderStdDevPopCorrectly() { MatchOperation operation = Aggregation.match().stdDevPop("size"); assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). @@ -15,7 +15,7 @@ public void shouldRenderStdDevPopCorrectly() { } - @Test + @Test // DATAMONGO - 3729 public void shouldRenderStdDevSampCorrectly() { MatchOperation operation = Aggregation.match().stdDevSamp("size"); assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java index ffe559e9f3..3345d85e4a 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java @@ -100,17 +100,17 @@ public void shouldNotExposeFields() { assertThat(operation.getFields().exposesSingleFieldOnly()).isFalse(); } - @Test + @Test // DATAMONGO - 3729 void shouldRendersStdDevPopCorrectly() { - ReplaceRootOperation operation = ReplaceRootDocumentOperation.builder().stdDevPop("quiz"); + ReplaceRootOperation operation = ReplaceRootOperation.builder().stdDevPop("quiz"); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); assertThat(dbObject).isEqualTo(Document.parse( "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevPop\" : \"$quiz\" } }}")); } - @Test + @Test // DATAMONGO - 3729 void shouldRendersStdDevSampCorrectly() { - ReplaceRootOperation operation = ReplaceRootDocumentOperation.builder().stdDevSamp("quiz"); + ReplaceRootOperation operation = ReplaceRootOperation.builder().stdDevSamp("quiz"); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); assertThat(dbObject).isEqualTo(Document.parse( "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevSamp\" : \"$quiz\" } }}")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java index 75bb3519c0..045e84c1cf 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java @@ -56,7 +56,7 @@ public void shouldRenderExpressionCorrectly() { + "$map : { input : \"$array\" , as : \"element\" , in : { $multiply : [ \"$$element\" , 10]} } " + "} }")); } - @Test + @Test // DATAMONGO - 3729 void shouldRendersStdDevPopCorrectly() { ReplaceWithOperation operation = ReplaceWithOperation.stdDevPop("quiz"); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); @@ -64,7 +64,7 @@ void shouldRendersStdDevPopCorrectly() { "{\"$replaceWith\" : { \"$stdDevPop\" : \"$quiz\" } }")); } - @Test + @Test // DATAMONGO - 3729 void shouldRendersStdDevSampCorrectly() { ReplaceWithOperation operation = ReplaceWithOperation.stdDevSamp("quiz"); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java index 085db0279a..c2718d755b 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java @@ -106,7 +106,7 @@ void rendersTargetValueExpressionCorrectly() { .containsExactly(Document.parse("{\"$set\" : {\"totalHomework\": { \"$sum\" : \"$homework\" }}}")); } - @Test + @Test // DATAMONGO - 3729 void rendersStdDevPopCorrectly() { assertThat(SetOperation.builder().set("totalQuiz").stdDevPop("quiz") .toPipelineStages(contextFor(ScoresWrapper.class))) @@ -114,7 +114,7 @@ void rendersStdDevPopCorrectly() { "{\"$set\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); } - @Test + @Test // DATAMONGO - 3729 void rendersStdDevSampCorrectly() { assertThat(SetOperation.builder().set("totalQuiz").stdDevSamp("quiz") .toPipelineStages(contextFor(ScoresWrapper.class))) diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java index 8ca21de503..4c2fa9775c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java @@ -87,7 +87,7 @@ void rendersMuiltipleOutputFields() { "{ $setWindowFields: { output: { f1 : { $sum: \"$quantity\", window: { documents: [ \"unbounded\", \"current\" ] } }, f2 : { $avg: \"$quantity\", window: { documents: [ -1, 0 ] } } } } }")); } - @Test // GH-3711 + @Test // DATAMONGO - 3729 void rendersOutputFieldsWithStdDevPopOperator() { SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // @@ -101,7 +101,7 @@ void rendersOutputFieldsWithStdDevPopOperator() { "{ $setWindowFields: { output: { f1 : { $stdDevPop: \"$quantity\", window: { documents: [ \"unbounded\", \"current\" ] } } } } }")); } - @Test // GH-3711 + @Test // DATAMONGO - 3729 void rendersOutputFieldsWithStdDevSampOperator() { SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // From 489222a93c86ce07df783ac258e4f1b77b0ee373 Mon Sep 17 00:00:00 2001 From: divyajnu08 Date: Mon, 30 Aug 2021 15:25:23 +0530 Subject: [PATCH 3/3] Review comments changes. --- .../core/aggregation/AddFieldsOperation.java | 53 ----------- .../core/aggregation/EvaluationOperators.java | 12 ++- .../core/aggregation/MatchOperation.java | 59 +++--------- .../core/aggregation/ProjectionOperation.java | 18 ---- .../aggregation/ReplaceRootOperation.java | 41 -------- .../aggregation/ReplaceWithOperation.java | 40 -------- .../core/aggregation/SetOperation.java | 48 ---------- .../aggregation/SetWindowFieldsOperation.java | 40 -------- .../AddFieldsOperationUnitTests.java | 11 ++- .../aggregation/AggregationUnitTests.java | 93 ------------------- .../aggregation/MatchOperationUnitTests.java | 8 +- .../ProjectionOperationUnitTests.java | 18 ---- .../ReplaceRootOperationUnitTests.java | 10 +- .../ReplaceWithOperationUnitTests.java | 9 +- .../aggregation/SetOperationUnitTests.java | 15 ++- .../SetWindowFieldsOperationUnitTests.java | 4 +- 16 files changed, 54 insertions(+), 425 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java index 7fd8f51ea4..186d420242 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java @@ -170,27 +170,6 @@ public AddFieldsOperationBuilder withValueOfExpression(String operation, Object. valueMap.put(field, new ExpressionProjection(operation, values)); return AddFieldsOperationBuilder.this; } - - @Override - public AddFieldsOperationBuilder stdDevPop(String fieldRef) { - return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); - } - - @Override - public AddFieldsOperationBuilder stdDevPop(AggregationExpression expression) { - return withValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); - } - - @Override - public AddFieldsOperationBuilder stdDevSamp(String fieldRef) { - return withValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); - } - - @Override - public AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression) { - return withValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); - } - }; } @@ -228,38 +207,6 @@ public interface ValueAppender { * @return new instance of {@link AddFieldsOperation}. */ AddFieldsOperationBuilder withValueOfExpression(String operation, Object... values); - - /** - * Adds the field with the value of {@code $stdDevPop} of the given field reference. - * - * @param fieldRef must not be {@literal null}. - * @return new instance of {@link AddFieldsOperationBuilder}. - */ - AddFieldsOperationBuilder stdDevPop(String AddFieldsOperationBuilder); - - /** - * Adds the field with the value of {@code $stdDevPop} of the given {@link AggregationExpression}.. - * - * @param fieldRef must not be {@literal null}. - * @return new instance of {@link AddFieldsOperationBuilder}. - */ - AddFieldsOperationBuilder stdDevPop(AggregationExpression expression); - - /** - * Adds the field with the value of {@code $stdDevSamp} of the given field reference. - * - * @param fieldRef must not be {@literal null}. - * @return new instance of {@link AddFieldsOperationBuilder}. - */ - AddFieldsOperationBuilder stdDevSamp(String fieldRef); - - /** - * Adds the field with the value of {@code $stdDevSamp} of the given {@link AggregationExpression}.. - * - * @param fieldRef must not be {@literal null}. - * @return new instance of {@link AddFieldsOperationBuilder}. - */ - AddFieldsOperationBuilder stdDevSamp(AggregationExpression expression); } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java index e7a25825d6..0fb8e25fab 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java @@ -1,11 +1,19 @@ package org.springframework.data.mongodb.core.aggregation; -import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.Abs; -import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.ArithmeticOperatorFactory; import org.springframework.util.Assert; public class EvaluationOperators { + /** + * Take the value resulting from the given fieldReference. + * + * @param fieldReference must not be {@literal null}. + * @return new instance of {@link EvaluationOperatorFactory}. + */ + public static EvaluationOperatorFactory valueOf(String fieldReference) { + return new EvaluationOperatorFactory(fieldReference); + } + /** * Take the value resulting from the given {@link AggregationExpression}. * diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java index 48e8d70769..c2796aaa03 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.core.aggregation; import org.bson.Document; +import org.springframework.data.mongodb.core.aggregation.EvaluationOperators.EvaluationOperatorFactory.Expr; import org.springframework.data.mongodb.core.query.CriteriaDefinition; import org.springframework.util.Assert; @@ -45,6 +46,7 @@ public MatchOperation() { this.criteriaDefinition = null; this.expression = null; } + /** * Creates a new {@link MatchOperation} for the given {@link CriteriaDefinition}. * @@ -58,19 +60,26 @@ public MatchOperation(CriteriaDefinition criteriaDefinition) { } /** - * Creates a new {@link MatchOperation} for the given {@link AggregationExpression}. + * Creates a new {@link MatchOperation} for the given {@link Expression}. * - * @param expression must not be {@literal null}. + * @param criteriaDefinition must not be {@literal null}. */ - private MatchOperation(AggregationExpression expression) { - + private MatchOperation(Expr expression) { Assert.notNull(expression, "Expression must not be null!"); this.criteriaDefinition = null; this.expression = expression; } + /** + * Creates a new {@link MatchOperation} for the given {@link AggregationExpression}. + * + * @param expression must not be {@literal null}. + */ + public MatchOperation withValueOf(AggregationExpression expression) { + Assert.notNull(expression, "Expression must not be null!"); + return new MatchOperation(EvaluationOperators.valueOf(expression).expr()); + } - /* * (non-Javadoc) * @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext) @@ -91,44 +100,4 @@ public Document toDocument(AggregationOperationContext context) { public String getOperator() { return "$match"; } - - /** - * Creates a new {@link MatchOperation} with the {@code stdDevPop} of the given fieldReference. - * - * @param fieldReference must not be {@literal null}. - * @return new instance of {@link MatchOperation} - */ - public MatchOperation stdDevPop(String fieldReference) { - return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevPop()).expr()); - } - - /** - * Creates a new {@link MatchOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null}. - * @return new instance of {@link MatchOperation} - */ - public MatchOperation stdDevPop(AggregationExpression expression) { - return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevPop()).expr()); - } - - /** - * Creates a new {@link MatchOperation} with the {@code stdDevSamp} of the given fieldReference. - * - * @param fieldReference must not be {@literal null}. - * @return new instance of {@link MatchOperation} - */ - public MatchOperation stdDevSamp(String fieldReference) { - return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()).expr()); - } - - /** - * Creates a new {@link MatchOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null}. - * @return new instance of {@link MatchOperation} - */ - public MatchOperation stdDevSamp(AggregationExpression expression) { - return new MatchOperation(EvaluationOperators.valueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()).expr()); - } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java index dcc8ef70c7..1879991ade 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java @@ -1307,24 +1307,6 @@ public ProjectionOperationBuilder let(Collection variables, return this.operation.and(VariableOperators.Let.define(variables).andApply(in)); } - /** - * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field - * - * @return never {@literal null}. - */ - public ProjectionOperationBuilder stdDevPop() { - return this.operation.and(AccumulatorOperators.StdDevPop.stdDevPopOf(getRequiredName())); - } - - /** - * Generates a {@code $stdDevPop} expression that takes the string representation of the previously mentioned field - * - * @return never {@literal null}. - */ - public ProjectionOperationBuilder stdDevSamp() { - return this.operation.and(AccumulatorOperators.StdDevSamp.stdDevSampOf(getRequiredName())); - } - private String getRequiredName() { Assert.state(name != null, "Projection field name must not be null!"); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java index 4e6ab7874e..f6dca04f58 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java @@ -167,47 +167,6 @@ public ReplaceRootOperation withDocument(Document document) { return new ReplaceRootDocumentOperation().andValuesOf(document); } - - /** - * Generates a new {@link ReplaceRootOperation} with the {@code stdDevPop} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link ReplaceRootOperation}. - */ - public ReplaceRootOperation stdDevPop(String fieldRef) { - return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); - } - - /** - * Generates a new {@link ReplaceRootOperation} with the {@code stdDevPop} of the given {@link AggregationExpression} - * - * @param expression must not be {@literal null} - * @return the final {@link ReplaceRootOperation}. - */ - public ReplaceRootOperation stdDevPop(AggregationExpression expression) { - return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevPop()); - } - - /** - * Generates a new {@link ReplaceRootOperation} with the {@code stdDevSamp} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link ReplaceRootOperation}. - */ - public ReplaceRootOperation stdDevSamp(String fieldRef) { - return new ReplaceRootOperation(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); - } - - /** - * Generates a new {@link ReplaceRootOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression} - * - * @param expression must not be {@literal null} - * @return the final {@link ReplaceRootOperation}. - */ - public ReplaceRootOperation stdDevSamp(AggregationExpression expression) { - return new ReplaceRootOperation(AccumulatorOperators.valueOf(expression).stdDevSamp()); - } - } /** diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java index 42524e09cb..0d53dbf5cf 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperation.java @@ -92,44 +92,4 @@ private static Object computeValue(Object value, AggregationOperationContext con public Document toDocument(AggregationOperationContext context) { return context.getMappedObject(new Document("$replaceWith", getReplacement().toDocumentExpression(context))); } - - /** - * Generates a new {@link ReplaceWithOperation} with the {@code stdDevPop} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link ReplaceWithOperation}. - */ - public static ReplaceWithOperation stdDevPop(String fieldRef) { - return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); - } - - /** - * Generates a new {@link ReplaceWithOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link ReplaceWithOperation}. - */ - public static ReplaceWithOperation stdDevPop(AggregationExpression expression) { - return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); - } - - /** - * Generates a new {@link ReplaceWithOperation} with the {@code stdDevSamp} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link ReplaceWithOperation}. - */ - public static ReplaceWithOperation stdDevSamp(String fieldRef) { - return replaceWithValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); - } - - /** - * Generates a new {@link ReplaceWithOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link ReplaceWithOperation}. - */ - public static ReplaceWithOperation stdDevSamp(AggregationExpression expression) { - return replaceWithValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); - } } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java index e703d0e505..6aecfd4563 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java @@ -155,22 +155,6 @@ public SetOperation withValueOfExpression(String operation, Object... values) { valueMap.put(field, new ExpressionProjection(operation, values)); return FieldAppender.this.build(); } - - public SetOperation stdDevPop(String fieldRef) { - return toValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevPop()); - } - - public SetOperation stdDevPop(AggregationExpression expression) { - return toValueOf(AccumulatorOperators.valueOf(expression).stdDevPop()); - } - - public SetOperation stdDevSamp(String fieldRef) { - return toValueOf(AccumulatorOperators.valueOf(fieldRef).stdDevSamp()); - } - - public SetOperation stdDevSamp(AggregationExpression expression) { - return toValueOf(AccumulatorOperators.valueOf(expression).stdDevSamp()); - } }; } @@ -209,38 +193,6 @@ public interface ValueAppender { * @return new instance of {@link SetOperation}. */ SetOperation withValueOfExpression(String operation, Object... values); - - /** - * Generates a new {@link SetOperation} with the {@code stdDevPop} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link SetOperation}. - */ - SetOperation stdDevPop(String fieldRef); - - /** - * Generates a new {@link SetOperation} with the {@code stdDevPop} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link SetOperation}. - */ - SetOperation stdDevPop(AggregationExpression expression); - - /** - * Generates a new {@link SetOperation} with the {@code stdDevSamp} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link SetOperation}. - */ - SetOperation stdDevSamp(String fieldRef); - - /** - * Generates a new {@link SetOperation} with the {@code stdDevSamp} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link SetOperation}. - */ - SetOperation stdDevSamp(AggregationExpression expression); } diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java index 01d339f6fb..9c40a0b642 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperation.java @@ -755,46 +755,6 @@ public SetWindowFieldsOperationBuilder as(String targetFieldName) { } }; } - - /** - * Generates a new {@link WindowChoice} with the {@code stdDevPop} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link WindowChoice}. - */ - public WindowChoice stdDevPop(String fieldReference) { - return output(AccumulatorOperators.valueOf(fieldReference).stdDevPop()); - } - - /** - * Generates a new {@link WindowChoice} with the {@code stdDevPop} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link WindowChoice}. - */ - public WindowChoice stdDevPop(AggregationExpression expression) { - return output(AccumulatorOperators.valueOf(expression).stdDevPop()); - } - - /** - * Generates a new {@link WindowChoice} with the {@code stdDevSamp} of the given field reference. - * - * @param fieldRef must not be {@literal null} - * @return the final {@link WindowChoice}. - */ - public WindowChoice stdDevSamp(String fieldReference) { - return output(AccumulatorOperators.valueOf(fieldReference).stdDevSamp()); - } - - /** - * Generates a new {@link WindowChoice} with the {@code stdDevSamp} of the given {@link AggregationExpression}. - * - * @param expression must not be {@literal null} - * @return the final {@link WindowChoice}. - */ - public WindowChoice stdDevSamp(AggregationExpression expression) { - return output(AccumulatorOperators.valueOf(expression).stdDevSamp()); - } /** * Interface to capture field name used to capture the computation result. diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java index 4a2375c788..637c2d2585 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperationUnitTests.java @@ -129,15 +129,16 @@ void exposesFieldsCorrectly() { @Test // DATAMONGO - 3729 void rendersStdDevPopCorrectly() { - assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevPop("quiz").build() - .toPipelineStages(contextFor(ScoresWrapper.class))) - .containsExactly(Document.parse( - "{\"$addFields\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); + assertThat(AddFieldsOperation.builder().addField("totalQuiz") + .withValue(ArithmeticOperators.valueOf("quiz").stdDevPop()).build() + .toPipelineStages(contextFor(ScoresWrapper.class))).containsExactly( + Document.parse("{\"$addFields\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); } @Test // DATAMONGO - 3729 void rendersStdDevSampCorrectly() { - assertThat(AddFieldsOperation.builder().addField("totalQuiz").stdDevSamp("quiz").build() + assertThat(AddFieldsOperation.builder().addField("totalQuiz") + .withValue(ArithmeticOperators.valueOf("quiz").stdDevSamp()).build() .toPipelineStages(contextFor(ScoresWrapper.class))) .containsExactly(Document.parse( "{\"$addFields\" : {\"totalQuiz\": { \"$stdDevSamp\" : \"$quiz\" } }}")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java index 1fe31d5bf7..087613cc31 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java @@ -134,29 +134,6 @@ void unwindOperationWithPreserveNullShouldBuildCorrectClause() { .containsEntry("$unwind.preserveNullAndEmptyArrays", true); } - @Test // DATAMONGO - 3729 - void addFieldsOperationWithStdDevPopShouldBuildCorrectly() { - Document agg = newAggregation( // - addFields().addField("totalQuiz").stdDevPop("quiz").build()) // - .toDocument("foo",Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$addFields\" : { \"totalQuiz\" : { \"$stdDevPop\" : \"$quiz\" }}}")); - } - - @Test // DATAMONGO - 3729 - void addFieldsOperationWithStdDevSampShouldBuildCorrectly() { - Document agg = newAggregation( // - addFields().addField("totalQuiz").stdDevSamp("quiz").build()) // - .toDocument("foo",Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$addFields\" : { \"totalQuiz\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); - } - - @Test // DATAMONGO-1550 void replaceRootOperationShouldBuildCorrectClause() { @@ -169,31 +146,7 @@ void replaceRootOperationShouldBuildCorrectClause() { Document unwind = ((List) agg.get("pipeline")).get(0); assertThat(unwind).containsEntry("$replaceRoot.newRoot", new Document("field", "value")); } - - @Test // DATAMONGO - 3729 - void replaceRootOperationWithStdDevPopShouldBuildCorrectly() { - Document agg = newAggregation( - replaceRoot().stdDevPop("quiz")) - .toDocument("foo", Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$replaceRoot\" : { \"newRoot\" : { \"$stdDevPop\" : \"$quiz\" }}}")); - } - - @Test // DATAMONGO - 3729 - void replaceRootOperationWithStdDevSampShouldBuildCorrectly() { - Document agg = newAggregation( - replaceRoot().stdDevSamp("quiz")) - .toDocument("foo", Aggregation.DEFAULT_CONTEXT); - - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$replaceRoot\" : { \"newRoot\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); - } - @Test // DATAMONGO-753 void matchOperationShouldNotChangeAvailableFields() { @@ -204,28 +157,6 @@ void matchOperationShouldNotChangeAvailableFields() { ).toDocument("foo", Aggregation.DEFAULT_CONTEXT); } - @Test // DATAMONGO - 3729 - void matchOperationWithStdDevPopShouldBuildCorrectly() { - Document agg = newAggregation( - match().stdDevPop("quiz")) - .toDocument("foo",Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$match\" : { \"$expr\" : { \"$stdDevPop\" : \"$quiz\" }}}")); - } - - @Test // DATAMONGO - 3729 - void matchOperationWithStdDevSampShouldBuildCorrectly() { - Document agg = newAggregation( - match().stdDevSamp("quiz")) - .toDocument("foo",Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$match\" : { \"$expr\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); - } - @Test // DATAMONGO-788 void referencesToGroupIdsShouldBeRenderedAsReferences() { @@ -667,31 +598,7 @@ void projectOnIdIsAlwaysValid() { assertThat(extractPipelineElement(target, 1, "$project")).isEqualTo(Document.parse(" { \"_id\" : \"$_id\" }")); } - - @Test // DATAMONGO - 3729 - void projectOperationWithStdDevPopShouldBuildCorrectly() { - Document agg = newAggregation( - project().and("quiz").stdDevPop().as("totalQuiz")) - .toDocument("foo", Aggregation.DEFAULT_CONTEXT); - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$project\" : { \"totalQuiz\" : { \"$stdDevPop\" : \"$quiz\" }}}")); - } - - @Test // DATAMONGO - 3729 - void projectOperationWithStdDevSampShouldBuildCorrectly() { - Document agg = newAggregation( - project().and("quiz").stdDevSamp().as("totalQuiz")) - .toDocument("foo", Aggregation.DEFAULT_CONTEXT); - - @SuppressWarnings("unchecked") - Document addField = ((List) agg.get("pipeline")).get(0); - assertThat(addField). - isEqualTo(Document.parse("{ \"$project\" : { \"totalQuiz\" : { \"$stdDevSamp\" : \"$quiz\" }}}")); - } - private Document extractPipelineElement(Document agg, int index, String operation) { List pipeline = (List) agg.get("pipeline"); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java index af3595747a..04d3824de1 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java @@ -9,17 +9,17 @@ class MatchOperationUnitTests { @Test // DATAMONGO - 3729 public void shouldRenderStdDevPopCorrectly() { - MatchOperation operation = Aggregation.match().stdDevPop("size"); + MatchOperation operation = Aggregation.match().withValueOf(ArithmeticOperators.valueOf("quiz").stdDevPop()); assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). - isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevPop\" : \"$size\" } } } ")); + isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevPop\" : \"$quiz\" } } } ")); } @Test // DATAMONGO - 3729 public void shouldRenderStdDevSampCorrectly() { - MatchOperation operation = Aggregation.match().stdDevSamp("size"); + MatchOperation operation = Aggregation.match().withValueOf(ArithmeticOperators.valueOf("quiz").stdDevSamp()); assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)). - isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevSamp\" : \"$size\" } } } ")); + isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevSamp\" : \"$quiz\" } } } ")); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java index 7b8e12115a..805fc10f38 100755 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java @@ -1463,24 +1463,6 @@ public void shouldRenderMinWithMultipleArgsAggregationExpression() { assertThat(agg).isEqualTo(Document.parse("{ $project: { examMin: { $min: [ \"$final\", \"$midterm\" ] } } }")); } - @Test // DATAMONGO- - public void shouldRenderStdDevPopExpressionCorrectly() { - - Document agg = new ProjectionOperation().and("scores").stdDevPop().as("stdDev") - .toDocument(Aggregation.DEFAULT_CONTEXT); - - assertThat(agg).isEqualTo(Document.parse("{ $project: { stdDev: { $stdDevPop: \"$scores\"} } }")); - } - - @Test // DATAMONGO- - public void shouldRenderStdSampExpressionCorrectly() { - - Document agg = new ProjectionOperation().and("scores").stdDevSamp().as("stdDev") - .toDocument(Aggregation.DEFAULT_CONTEXT); - - assertThat(agg).isEqualTo(Document.parse("{ $project: { stdDev: { $stdDevSamp: \"$scores\"} } }")); - } - @Test // DATAMONGO-1536 public void shouldRenderStdDevPopAggregationExpression() { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java index 3345d85e4a..4677b56dfa 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperationUnitTests.java @@ -102,15 +102,17 @@ public void shouldNotExposeFields() { @Test // DATAMONGO - 3729 void shouldRendersStdDevPopCorrectly() { - ReplaceRootOperation operation = ReplaceRootOperation.builder().stdDevPop("quiz"); + ReplaceRootOperation operation = ReplaceRootOperation.builder() + .withValueOf(ArithmeticOperators.valueOf("quiz").stdDevPop()); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(dbObject).isEqualTo(Document.parse( - "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevPop\" : \"$quiz\" } }}")); + assertThat(dbObject) + .isEqualTo(Document.parse("{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevPop\" : \"$quiz\" } }}")); } @Test // DATAMONGO - 3729 void shouldRendersStdDevSampCorrectly() { - ReplaceRootOperation operation = ReplaceRootOperation.builder().stdDevSamp("quiz"); + ReplaceRootOperation operation = ReplaceRootOperation.builder() + .withValueOf(ArithmeticOperators.valueOf("quiz").stdDevSamp()); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); assertThat(dbObject).isEqualTo(Document.parse( "{\"$replaceRoot\" : {\"newRoot\": { \"$stdDevSamp\" : \"$quiz\" } }}")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java index 045e84c1cf..666d7a4363 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ReplaceWithOperationUnitTests.java @@ -58,15 +58,16 @@ public void shouldRenderExpressionCorrectly() { @Test // DATAMONGO - 3729 void shouldRendersStdDevPopCorrectly() { - ReplaceWithOperation operation = ReplaceWithOperation.stdDevPop("quiz"); + ReplaceWithOperation operation = ReplaceWithOperation + .replaceWithValueOf(ArithmeticOperators.valueOf("quiz").stdDevPop()); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); - assertThat(dbObject).isEqualTo(Document.parse( - "{\"$replaceWith\" : { \"$stdDevPop\" : \"$quiz\" } }")); + assertThat(dbObject).isEqualTo(Document.parse("{\"$replaceWith\" : { \"$stdDevPop\" : \"$quiz\" } }")); } @Test // DATAMONGO - 3729 void shouldRendersStdDevSampCorrectly() { - ReplaceWithOperation operation = ReplaceWithOperation.stdDevSamp("quiz"); + ReplaceWithOperation operation = ReplaceWithOperation + .replaceWithValueOf(ArithmeticOperators.valueOf("quiz").stdDevSamp()); Document dbObject = operation.toDocument(Aggregation.DEFAULT_CONTEXT); assertThat(dbObject).isEqualTo(Document.parse( "{\"$replaceWith\" : { \"$stdDevSamp\" : \"$quiz\" } }")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java index c2718d755b..f146ae55c2 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java @@ -108,18 +108,17 @@ void rendersTargetValueExpressionCorrectly() { @Test // DATAMONGO - 3729 void rendersStdDevPopCorrectly() { - assertThat(SetOperation.builder().set("totalQuiz").stdDevPop("quiz") - .toPipelineStages(contextFor(ScoresWrapper.class))) - .containsExactly(Document.parse( - "{\"$set\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); + assertThat(SetOperation.builder().set("totalQuiz").toValueOf(ArithmeticOperators.valueOf("quiz").stdDevPop()) + .toPipelineStages(contextFor(ScoresWrapper.class))).containsExactly( + Document.parse("{\"$set\" : {\"totalQuiz\": { \"$stdDevPop\" : \"$quiz\" } }}")); } @Test // DATAMONGO - 3729 void rendersStdDevSampCorrectly() { - assertThat(SetOperation.builder().set("totalQuiz").stdDevSamp("quiz") - .toPipelineStages(contextFor(ScoresWrapper.class))) - .containsExactly(Document.parse( - "{\"$set\" : {\"totalQuiz\": { \"$stdDevSamp\" : \"$quiz\" } }}")); + assertThat( + SetOperation.builder().set("totalQuiz").toValueOf(ArithmeticOperators.valueOf("quiz").stdDevSamp()) + .toPipelineStages(contextFor(ScoresWrapper.class))).containsExactly( + Document.parse("{\"$set\" : {\"totalQuiz\": { \"$stdDevSamp\" : \"$quiz\" } }}")); } @Test // DATAMONGO-2331 diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java index 4c2fa9775c..9d1865df2e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetWindowFieldsOperationUnitTests.java @@ -91,7 +91,7 @@ void rendersMuiltipleOutputFields() { void rendersOutputFieldsWithStdDevPopOperator() { SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // - .stdDevPop("qty") + .output(ArithmeticOperators.valueOf("qty").stdDevPop()) .within(Windows.documents().fromUnbounded().toCurrent().build()) // .as("f1") // .build(); // @@ -105,7 +105,7 @@ void rendersOutputFieldsWithStdDevPopOperator() { void rendersOutputFieldsWithStdDevSampOperator() { SetWindowFieldsOperation setWindowFieldsOperation = SetWindowFieldsOperation.builder() // - .stdDevSamp("qty") + .output(ArithmeticOperators.valueOf("qty").stdDevSamp()) .within(Windows.documents().fromUnbounded().toCurrent().build()) // .as("f1") // .build(); //