Browse Source

Add support for `$derivative` aggregation operator.

Closes: #3716
Original pull request: #3742.
pull/3765/head
Christoph Strobl 4 years ago committed by Mark Paluch
parent
commit
82b33331fc
No known key found for this signature in database
GPG Key ID: 4406B84C1661DCD1
  1. 55
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java
  2. 1
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
  3. 7
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java
  4. 5
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java

55
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java

@ -26,7 +26,9 @@ import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Mi @@ -26,7 +26,9 @@ import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Mi
import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.StdDevPop;
import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.StdDevSamp;
import org.springframework.data.mongodb.core.aggregation.AccumulatorOperators.Sum;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Gateway to {@literal Arithmetic} aggregation operations that perform math operations on numbers.
@ -591,6 +593,31 @@ public class ArithmeticOperators { @@ -591,6 +593,31 @@ public class ArithmeticOperators {
return round().place(place);
}
/**
* Creates new {@link AggregationExpression} that calculates the mathematical derivative value.
*
* @return new instance of {@link Derivative}.
* @since 3.3
*/
public Derivative derivative() {
return derivative(null);
}
/**
* Creates new {@link AggregationExpression} that calculates the mathematical derivative value.
*
* @param unit The time unit ({@literal week, day, hour, minute, second, millisecond}) to apply can be
* {@literal null}.
* @return new instance of {@link Derivative}.
* @since 3.3
*/
public Derivative derivative(@Nullable String unit) {
Derivative derivative = usesFieldRef() ? Derivative.derivativeOf(fieldReference)
: Derivative.derivativeOf(expression);
return StringUtils.hasText(unit) ? derivative.unit(unit) : derivative;
}
private boolean usesFieldRef() {
return fieldReference != null;
}
@ -1724,4 +1751,32 @@ public class ArithmeticOperators { @@ -1724,4 +1751,32 @@ public class ArithmeticOperators {
return "$round";
}
}
public static class Derivative extends AbstractAggregationExpression {
private Derivative(Object value) {
super(value);
}
public static Derivative derivativeOf(String fieldReference) {
return new Derivative(Collections.singletonMap("input", Fields.field(fieldReference)));
}
public static Derivative derivativeOf(AggregationExpression expression) {
return new Derivative(Collections.singletonMap("input", expression));
}
public static Derivative derivativeOfValue(Number value) {
return new Derivative(Collections.singletonMap("input", value));
}
public Derivative unit(String unit) {
return new Derivative(append("unit", unit));
}
@Override
protected String getMongoMethod() {
return "$derivative";
}
}
}

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

@ -91,6 +91,7 @@ public class MethodReferenceNode extends ExpressionNode { @@ -91,6 +91,7 @@ public class MethodReferenceNode extends ExpressionNode {
map.put("subtract", arrayArgRef().forOperator("$subtract"));
map.put("trunc", singleArgRef().forOperator("$trunc"));
map.put("round", arrayArgRef().forOperator("$round"));
map.put("derivative", mapArgRef().forOperator("$derivative").mappingParametersTo("input", "unit"));
// STRING OPERATORS
map.put("concat", arrayArgRef().forOperator("$concat"));

7
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java

@ -59,4 +59,11 @@ public class ArithmeticOperatorsUnitTests { @@ -59,4 +59,11 @@ public class ArithmeticOperatorsUnitTests {
.toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(new Document("$round", Arrays.asList("$field", new Document("$first", "$source"))));
}
@Test // GH-3716
void rendersDerivativeCorrectly() {
assertThat(valueOf("miles").derivative("hour").toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(Document.parse("{ $derivative: { input: \"$miles\", unit: \"hour\" } }"));
}
}

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

@ -989,6 +989,11 @@ public class SpelExpressionTransformerUnitTests { @@ -989,6 +989,11 @@ public class SpelExpressionTransformerUnitTests {
}
@Nullable
@Test // GH-3716
void shouldRenderDerivative() {
assertThat(transform("derivative(miles, 'hour')")).isEqualTo(Document.parse("{ \"$derivative\" : { input : '$miles', unit : 'hour'} }"));
}
private Object transform(String expression, Object... params) {
Object result = transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
return result == null ? null : (!(result instanceof org.bson.Document) ? result.toString() : result);

Loading…
Cancel
Save