Add support for $integral aggregation operator.
Closes: #3721 Original pull request: #3746.
This commit is contained in:
committed by
Mark Paluch
parent
fd0a402c99
commit
df2b2a2f68
@@ -216,6 +216,27 @@ public class ArithmeticOperators {
|
||||
return usesFieldRef() ? Floor.floorValueOf(fieldReference) : Floor.floorValueOf(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the approximation for the mathematical integral value.
|
||||
*
|
||||
* @return new instance of {@link Integral}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public Integral integral() {
|
||||
return usesFieldRef() ? Integral.integralOf(fieldReference) : Integral.integralOf(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the approximation for the mathematical integral value.
|
||||
*
|
||||
* @param unit the unit of measure.
|
||||
* @return new instance of {@link Integral}.
|
||||
* @since 3.3
|
||||
*/
|
||||
public Integral integral(String unit) {
|
||||
return integral().unit(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that calculates the natural logarithm ln (i.e loge) of the assoicated
|
||||
* number.
|
||||
@@ -520,8 +541,8 @@ public class ArithmeticOperators {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the value of the given
|
||||
* field to calculate the population covariance of the two.
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the value of the
|
||||
* given field to calculate the population covariance of the two.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link CovariancePop}.
|
||||
@@ -532,8 +553,8 @@ public class ArithmeticOperators {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the result of the given
|
||||
* {@link AggregationExpression expression} to calculate the population covariance of the two.
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the result of the
|
||||
* given {@link AggregationExpression expression} to calculate the population covariance of the two.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link CovariancePop}.
|
||||
@@ -548,8 +569,8 @@ public class ArithmeticOperators {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the value of the given
|
||||
* field to calculate the sample covariance of the two.
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the value of the
|
||||
* given field to calculate the sample covariance of the two.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link CovariancePop}.
|
||||
@@ -560,8 +581,8 @@ public class ArithmeticOperators {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the result of the given
|
||||
* {@link AggregationExpression expression} to calculate the sample covariance of the two.
|
||||
* Creates new {@link AggregationExpression} that uses the previous input (field/expression) and the result of the
|
||||
* given {@link AggregationExpression expression} to calculate the sample covariance of the two.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link CovariancePop}.
|
||||
@@ -1798,4 +1819,54 @@ public class ArithmeticOperators {
|
||||
return "$derivative";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object to represent an {@link AggregationExpression expression} that calculates the approximation for the
|
||||
* mathematical integral value.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 3.3
|
||||
*/
|
||||
public static class Integral extends AbstractAggregationExpression {
|
||||
|
||||
private Integral(Object value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of {@link Integral} for the value stored at the given field holding a numeric value.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link Integral}.
|
||||
*/
|
||||
public static Integral integralOf(String fieldReference) {
|
||||
return new Integral(Collections.singletonMap("input", Fields.field(fieldReference)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of {@link Integral} for the value provided by the given expression that resolves to a
|
||||
* numeric value.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link Integral}.
|
||||
*/
|
||||
public static Integral integralOf(AggregationExpression expression) {
|
||||
return new Integral(Collections.singletonMap("input", expression));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the unit of measure.
|
||||
*
|
||||
* @param unit the unit of measure.
|
||||
* @return new instance of {@link Integral}.
|
||||
*/
|
||||
public Integral unit(String unit) {
|
||||
return new Integral(append("unit", unit));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$integral";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
map.put("trunc", singleArgRef().forOperator("$trunc"));
|
||||
map.put("round", arrayArgRef().forOperator("$round"));
|
||||
map.put("derivative", mapArgRef().forOperator("$derivative").mappingParametersTo("input", "unit"));
|
||||
map.put("integral", mapArgRef().forOperator("$integral").mappingParametersTo("input", "unit"));
|
||||
|
||||
// STRING OPERATORS
|
||||
map.put("concat", arrayArgRef().forOperator("$concat"));
|
||||
|
||||
@@ -68,4 +68,14 @@ class ArithmeticOperatorsUnitTests {
|
||||
valueOf("miles").derivative(SetWindowFieldsOperation.WindowUnits.HOUR).toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo(Document.parse("{ $derivative: { input: \"$miles\", unit: \"hour\" } }"));
|
||||
}
|
||||
|
||||
@Test // GH-3721
|
||||
void rendersIntegral() {
|
||||
assertThat(valueOf("kilowatts").integral().toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(Document.parse("{ $integral : { input : \"$kilowatts\" } }"));
|
||||
}
|
||||
|
||||
@Test // GH-3721
|
||||
void rendersIntegralWithUnit() {
|
||||
assertThat(valueOf("kilowatts").integral("hour").toDocument(Aggregation.DEFAULT_CONTEXT)).isEqualTo(Document.parse("{ $integral : { input : \"$kilowatts\", unit : \"hour\" } }"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -994,6 +994,16 @@ public class SpelExpressionTransformerUnitTests {
|
||||
assertThat(transform("derivative(miles, 'hour')")).isEqualTo(Document.parse("{ \"$derivative\" : { input : '$miles', unit : 'hour'} }"));
|
||||
}
|
||||
|
||||
@Test // GH-3721
|
||||
public void shouldRenderIntegral() {
|
||||
assertThat(transform("integral(field)")).isEqualTo(Document.parse("{ \"$integral\" : { \"input\" : \"$field\" }}"));
|
||||
}
|
||||
|
||||
@Test // GH-3721
|
||||
public void shouldIntegralWithUnit() {
|
||||
assertThat(transform("integral(field, 'hour')")).isEqualTo(Document.parse("{ \"$integral\" : { \"input\" : \"$field\", \"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);
|
||||
|
||||
Reference in New Issue
Block a user