Browse Source

Add support for `$expr` operator.

Also, allow construction of $match with an AggregationExpression.

Closes #3790
pull/3802/head
divyajnu08 4 years ago committed by Mark Paluch
parent
commit
e71ec874ab
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 1
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java
  2. 12
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java
  3. 109
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java
  4. 39
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java
  5. 1
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java
  6. 1
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java
  7. 26
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java
  8. 1
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java

1
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/AddFieldsOperation.java

@ -201,4 +201,5 @@ public class AddFieldsOperation extends DocumentEnhancingOperation { @@ -201,4 +201,5 @@ public class AddFieldsOperation extends DocumentEnhancingOperation {
AddFieldsOperationBuilder withValueOfExpression(String operation, Object... values);
}
}
}

12
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java

@ -498,7 +498,17 @@ public class Aggregation { @@ -498,7 +498,17 @@ public class Aggregation {
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.

109
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java

@ -0,0 +1,109 @@ @@ -0,0 +1,109 @@
package org.springframework.data.mongodb.core.aggregation;
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}.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link EvaluationOperatorFactory}.
*/
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 is a valid aggregation expression.
*
* @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 Expr}.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link Expr}.
*/
public static Expr valueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null!");
return new Expr(expression);
}
}
private boolean usesFieldRef() {
return fieldReference != null;
}
}
}

39
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/MatchOperation.java

@ -16,6 +16,7 @@ @@ -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;
@ -36,7 +37,16 @@ import org.springframework.util.Assert; @@ -36,7 +37,16 @@ import org.springframework.util.Assert;
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;
}
/**
* Creates a new {@link MatchOperation} for the given {@link CriteriaDefinition}.
*
@ -46,14 +56,39 @@ public class MatchOperation implements AggregationOperation { @@ -46,14 +56,39 @@ public class MatchOperation implements AggregationOperation {
Assert.notNull(criteriaDefinition, "Criteria must not be null!");
this.criteriaDefinition = criteriaDefinition;
this.expression = null;
}
/**
* Creates a new {@link MatchOperation} for the given {@link Expression}.
*
* @param criteriaDefinition must not be {@literal null}.
*/
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)
*/
@Override
public Document toDocument(AggregationOperationContext context) {
if(expression != null) {
return new Document(getOperator(), expression.toDocument());
}
return new Document(getOperator(), context.getMappedObject(criteriaDefinition.getCriteriaObject()));
}

1
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ReplaceRootOperation.java

@ -21,6 +21,7 @@ import java.util.Collections; @@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List;
import org.bson.Document;
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
import org.springframework.expression.spel.ast.Projection;
import org.springframework.util.Assert;

1
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/SetOperation.java

@ -193,5 +193,6 @@ public class SetOperation extends DocumentEnhancingOperation { @@ -193,5 +193,6 @@ public class SetOperation extends DocumentEnhancingOperation {
*/
SetOperation withValueOfExpression(String operation, Object... values);
}
}
}

26
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/MatchOperationUnitTests.java

@ -0,0 +1,26 @@ @@ -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 // DATAMONGO - 3729
public void shouldRenderStdDevPopCorrectly() {
MatchOperation operation = Aggregation.match().withValueOf(ArithmeticOperators.valueOf("quiz").stdDevPop());
assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)).
isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevPop\" : \"$quiz\" } } } "));
}
@Test // DATAMONGO - 3729
public void shouldRenderStdDevSampCorrectly() {
MatchOperation operation = Aggregation.match().withValueOf(ArithmeticOperators.valueOf("quiz").stdDevSamp());
assertThat(operation.toDocument(Aggregation.DEFAULT_CONTEXT)).
isEqualTo(Document.parse("{ $match: { \"$expr\" : { \"$stdDevSamp\" : \"$quiz\" } } } "));
}
}

1
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SetOperationUnitTests.java

@ -21,6 +21,7 @@ import java.util.List; @@ -21,6 +21,7 @@ import java.util.List;
import org.bson.Document;
import org.junit.jupiter.api.Test;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.convert.NoOpDbRefResolver;
import org.springframework.data.mongodb.core.convert.QueryMapper;

Loading…
Cancel
Save