diff --git a/pom.xml b/pom.xml
index b688f3ee50..a63519e213 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3721-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-benchmarks/pom.xml b/spring-data-mongodb-benchmarks/pom.xml
index 0033bd11d5..e3a7085bff 100644
--- a/spring-data-mongodb-benchmarks/pom.xml
+++ b/spring-data-mongodb-benchmarks/pom.xml
@@ -7,7 +7,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3721-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index f62c8dc7f4..a8f7405fb3 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -14,7 +14,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3721-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 1f157e75bc..20a7abffde 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 3.3.0-SNAPSHOT
+ 3.3.0-GH-3721-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java
index 6053f3ae1b..027052836b 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperators.java
@@ -208,6 +208,27 @@ public Floor floor() {
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.
@@ -1665,4 +1686,52 @@ protected String getMongoMethod() {
return "$round";
}
}
+
+ /**
+ * 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";
+ }
+ }
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
index 5a2c48bc20..94e8d0a80e 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/spel/MethodReferenceNode.java
@@ -85,6 +85,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("integral", mapArgRef().forOperator("$integral").mappingParametersTo("input", "unit"));
// STRING OPERATORS
map.put("concat", arrayArgRef().forOperator("$concat"));
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java
index 940a315239..03efd67298 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArithmeticOperatorsUnitTests.java
@@ -59,4 +59,14 @@ void roundShouldWithPlaceFromExpression() {
.toDocument(Aggregation.DEFAULT_CONTEXT))
.isEqualTo(new Document("$round", Arrays.asList("$field", new Document("$first", "$source"))));
}
+
+ @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\" } }"));
+ }
}
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
index b67beed126..56dbe85b31 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/SpelExpressionTransformerUnitTests.java
@@ -946,6 +946,16 @@ public void shouldRenderRoundWithPlace() {
assertThat(transform("round(field, 2)")).isEqualTo(Document.parse("{ \"$round\" : [\"$field\", 2]}"));
}
+ @Test // GH-3721
+ public void shouldIntegral() {
+ 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);