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`