diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java index bb69ebf5f..d50ef8afa 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java @@ -35,6 +35,7 @@ import org.springframework.util.Assert; * @author Christoph Strobl * @author Mark Paluch * @author Shashank Sharma + * @author Divya Srivastava * @since 1.0 */ public class ArrayOperators { @@ -364,10 +365,11 @@ public class ArrayOperators { } /** - * Creates new {@link AggregationExpression} that return the first element in the given array. + * Creates new {@link AggregationExpression} that return the first element in the associated array. * NOTE: Requires MongoDB 4.4 or later. * * @return new instance of {@link First}. + * @since 3.4 */ public First first() { @@ -382,7 +384,8 @@ public class ArrayOperators { * Creates new {@link AggregationExpression} that return the last element in the given array. * NOTE: Requires MongoDB 4.4 or later. * - * @return new instance of {@link First}. + * @return new instance of {@link Last}. + * @since 3.4 */ public Last last() { @@ -1847,6 +1850,9 @@ public class ArrayOperators { * {@link AggregationExpression} for {@code $first} that returns the first element in an array.
* NOTE: Requires MongoDB 4.4 or later. * + * @author Divya Srivastava + * @author Christoph Strobl + * @since 3.4 */ public static class First extends AbstractAggregationExpression { @@ -1875,7 +1881,7 @@ public class ArrayOperators { } /** - * Returns the first element of the array of the given {@link AggregationExpression expression}. + * Returns the first element of the array computed by the given {@link AggregationExpression expression}. * * @param expression must not be {@literal null}. * @return new instance of {@link First}. @@ -1898,6 +1904,9 @@ public class ArrayOperators { * {@link AggregationExpression} for {@code $last} that returns the last element in an array.
* NOTE: Requires MongoDB 4.4 or later. * + * @author Divya Srivastava + * @author Christoph Strobl + * @since 3.4 */ public static class Last extends AbstractAggregationExpression { @@ -1906,7 +1915,7 @@ public class ArrayOperators { } /** - * Returns the first element in the given array. + * Returns the last element in the given array. * * @param array must not be {@literal null}. * @return new instance of {@link Last}. @@ -1926,7 +1935,7 @@ public class ArrayOperators { } /** - * Returns the last element of the array of the given {@link AggregationExpression expression}. + * Returns the last element of the array computed buy the given {@link AggregationExpression expression}. * * @param expression must not be {@literal null}. * @return new instance of {@link Last}. @@ -1944,5 +1953,4 @@ public class ArrayOperators { return "$last"; } } - } 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 f5032868c..0e0145571 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 @@ -137,7 +137,9 @@ public class MethodReferenceNode extends ExpressionNode { map.put("concatArrays", arrayArgRef().forOperator("$concatArrays")); map.put("filter", mapArgRef().forOperator("$filter") // .mappingParametersTo("input", "as", "cond")); + map.put("first", singleArgRef().forOperator("$first")); map.put("isArray", singleArgRef().forOperator("$isArray")); + map.put("last", singleArgRef().forOperator("$last")); map.put("size", singleArgRef().forOperator("$size")); map.put("slice", arrayArgRef().forOperator("$slice")); map.put("reverseArray", singleArgRef().forOperator("$reverseArray")); diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArrayOperatorsUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArrayOperatorsUnitTests.java index 56a7bf7ac..4e637918e 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArrayOperatorsUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ArrayOperatorsUnitTests.java @@ -23,7 +23,6 @@ import java.util.List; import org.bson.Document; import org.junit.jupiter.api.Test; - import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayToObject; /** @@ -31,6 +30,7 @@ import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayToO * * @author Christoph Strobl * @author Shashank Sharma + * @author Divya Srivastava * @currentRead Royal Assassin - Robin Hobb */ public class ArrayOperatorsUnitTests { @@ -130,46 +130,45 @@ public class ArrayOperatorsUnitTests { .isEqualTo("{ \"$in\" : [\"$userName\", " + VALUE_LIST_STRING + "] }"); } - @Test + @Test // GH-3694 public void firstWithValueList() { assertThat(ArrayOperators.arrayOf(VALUE_LIST).first().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ \"$first\" : " + VALUE_LIST_STRING + "}"); } - @Test + @Test // GH-3694 public void firstWithExpression() { assertThat(ArrayOperators.arrayOf(EXPRESSION).first().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ \"$first\" : " + EXPRESSION_STRING + "}"); } - @Test + @Test // GH-3694 public void firstWithFieldReference() { assertThat(ArrayOperators.arrayOf("field").first().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ $first : \"$field\" }"); } - @Test + @Test // GH-3694 public void lastWithValueList() { assertThat(ArrayOperators.arrayOf(VALUE_LIST).last().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ \"$last\" : " + VALUE_LIST_STRING + "}"); } - @Test + @Test // GH-3694 public void lastWithExpression() { assertThat(ArrayOperators.arrayOf(EXPRESSION).last().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ \"$last\" : " + EXPRESSION_STRING + "}"); } - @Test + @Test // GH-3694 public void lastWithFieldReference() { assertThat(ArrayOperators.arrayOf("field").last().toDocument(Aggregation.DEFAULT_CONTEXT)) .isEqualTo("{ $last : \"$field\" }"); } - } 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 e308124eb..490322003 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 @@ -411,6 +411,16 @@ public class SpelExpressionTransformerUnitTests { assertThat(transform("arrayElemAt(a, 10)")).isEqualTo("{ \"$arrayElemAt\" : [ \"$a\" , 10]}"); } + @Test // GH-3694 + void shouldRenderMethodReferenceNodeFirst() { + assertThat(transform("first(a)")).isEqualTo("{ \"$first\" : \"$a\" }"); + } + + @Test // GH-3694 + void shouldRenderMethodReferenceNodeLast() { + assertThat(transform("last(a)")).isEqualTo("{ \"$last\" : \"$a\" }"); + } + @Test // DATAMONGO-1530 void shouldRenderMethodReferenceNodeConcatArrays() { assertThat(transform("concatArrays(a, b, c)")) @@ -879,7 +889,6 @@ public class SpelExpressionTransformerUnitTests { .isEqualTo("{ \"$replaceAll\" : {\"input\" : \"$field\" , \"find\" : \"bar\" , \"replacement\" : \"baz\"}}"); } - @Test // DATAMONGO-2077 void shouldRenderConvertWithoutOptionalParameters() { diff --git a/src/main/asciidoc/reference/aggregation-framework.adoc b/src/main/asciidoc/reference/aggregation-framework.adoc index c5db5f30a..3530ada88 100644 --- a/src/main/asciidoc/reference/aggregation-framework.adoc +++ b/src/main/asciidoc/reference/aggregation-framework.adoc @@ -94,7 +94,7 @@ At the time of this writing, we provide support for the following Aggregation Op | `eq` (+++*+++ via `is`), `gt`, `gte`, `lt`, `lte`, `ne` | Array Aggregation Operators -| `arrayElementAt`, `arrayToObject`, `concatArrays`, `filter`, `in`, `indexOfArray`, `isArray`, `range`, `reverseArray`, `reduce`, `size`, `slice`, `zip` +| `arrayElementAt`, `arrayToObject`, `concatArrays`, `filter`, `first`, `in`, `indexOfArray`, `isArray`, `last`, range`, `reverseArray`, `reduce`, `size`, `slice`, `zip` | Literal Operators | `literal`