Browse Source

Add support for $locf aggregation operator.

See #4139
Original pull request: #4182.
pull/4212/head
Christoph Strobl 3 years ago committed by Mark Paluch
parent
commit
9217821472
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 52
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperators.java
  2. 3
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
  3. 8
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperatorsUnitTests.java
  4. 5
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

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

@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
package org.springframework.data.mongodb.core.aggregation;
import org.bson.Document;
import org.springframework.data.mongodb.core.query.CriteriaDefinition;
import org.springframework.util.Assert;
@ -24,6 +23,7 @@ import org.springframework.util.Assert; @@ -24,6 +23,7 @@ import org.springframework.util.Assert;
* Gateway to {@literal evaluation operators} such as {@literal $expr}.
*
* @author Divya Srivastava
* @author Christoph Strobl
* @since 3.3
*/
public class EvaluationOperators {
@ -86,6 +86,15 @@ public class EvaluationOperators { @@ -86,6 +86,15 @@ public class EvaluationOperators {
return usesFieldRef() ? Expr.valueOf(fieldReference) : Expr.valueOf(expression);
}
/**
* Creates new {@link AggregationExpression} that is a valid aggregation expression.
*
* @return new instance of {@link Expr}.
*/
public LastObservationCarriedForward locf() {
return usesFieldRef() ? LastObservationCarriedForward.locfValueOf(fieldReference) : LastObservationCarriedForward.locfValueOf(expression);
}
/**
* Allows the use of aggregation expressions within the query language.
*/
@ -152,4 +161,45 @@ public class EvaluationOperators { @@ -152,4 +161,45 @@ public class EvaluationOperators {
}
}
/**
* Sets {@literal null} and missing values to the last non-null value.
*
* @since 4.0
*/
public static class LastObservationCarriedForward extends AbstractAggregationExpression {
private LastObservationCarriedForward(Object value) {
super(value);
}
@Override
protected String getMongoMethod() {
return "$locf";
}
/**
* Creates new {@link EvaluationOperatorFactory.Expr}.
*
* @param fieldReference must not be {@literal null}.
* @return new instance of {@link EvaluationOperatorFactory.Expr}.
*/
public static LastObservationCarriedForward locfValueOf(String fieldReference) {
Assert.notNull(fieldReference, "FieldReference must not be null");
return new LastObservationCarriedForward(Fields.field(fieldReference));
}
/**
* Creates new {@link LastObservationCarriedForward}.
*
* @param expression must not be {@literal null}.
* @return new instance of {@link LastObservationCarriedForward}.
*/
public static LastObservationCarriedForward locfValueOf(AggregationExpression expression) {
Assert.notNull(expression, "Expression must not be null");
return new LastObservationCarriedForward(expression);
}
}
}

3
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java

@ -251,6 +251,9 @@ public class MethodReferenceNode extends ExpressionNode { @@ -251,6 +251,9 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("toString", singleArgRef().forOperator("$toString"));
map.put("degreesToRadians", singleArgRef().forOperator("$degreesToRadians"));
// expression operators
map.put("locf", singleArgRef().forOperator("$locf"));
FUNCTIONS = Collections.unmodifiableMap(map);
}

8
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/EvaluationOperatorsUnitTests.java

@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test; @@ -23,6 +23,7 @@ import org.junit.jupiter.api.Test;
* Unit tests for {@link EvaluationOperators}.
*
* @author Mark Paluch
* @author Christoph Strobl
*/
class EvaluationOperatorsUnitTests {
@ -32,4 +33,11 @@ class EvaluationOperatorsUnitTests { @@ -32,4 +33,11 @@ class EvaluationOperatorsUnitTests {
assertThat(EvaluationOperators.valueOf("foo").expr().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $expr: \"$foo\" }");
}
@Test // GH-4139
void shouldRenderLocfCorrectly() {
assertThat(EvaluationOperators.valueOf("foo").locf().toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo("{ $locf: \"$foo\" }");
}
}

5
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

@ -1250,6 +1250,11 @@ public class SpelExpressionTransformerUnitTests { @@ -1250,6 +1250,11 @@ public class SpelExpressionTransformerUnitTests {
void shouldTsSecond() {
assertThat(transform("tsSecond(saleTimestamp)")).isEqualTo("{ $tsSecond: \"$saleTimestamp\" }");
}
@Test // GH-4139
void shouldRenderLocf() {
assertThat(transform("locf(price)")).isEqualTo("{ $locf: \"$price\" }");
}
private Document transform(String expression, Object... params) {
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);

Loading…
Cancel
Save