Support aggregation operators $first and $last via expression method reference.
This commit registers the first(...) and last(...) methods for transformation via SpEL. Also update reference and java documentation and add issue reference to tests. Original Pull Request: #3866
This commit is contained in:
@@ -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.
|
||||
* <strong>NOTE:</strong> 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.
|
||||
* <strong>NOTE:</strong> 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. <br />
|
||||
* <strong>NOTE:</strong> 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. <br />
|
||||
* <strong>NOTE:</strong> 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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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\" }");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
@@ -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`
|
||||
|
||||
Reference in New Issue
Block a user