Add support for $sortArray aggregation operator.
See #4139 Original pull request: #4182.
This commit is contained in:
committed by
Mark Paluch
parent
d4a6614c11
commit
714b23e0ce
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.AsBuilder;
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression;
|
||||
import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedField;
|
||||
@@ -315,6 +316,21 @@ public class ArrayOperators {
|
||||
.withInitialValue(initialValue).reduce(expressions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that takes the associated array and sorts it by the given {@link Sort order}.
|
||||
*
|
||||
* @return new instance of {@link SortArray}.
|
||||
* @since 4.0
|
||||
*/
|
||||
public SortArray sort(Sort sort) {
|
||||
|
||||
if (usesFieldRef()) {
|
||||
return SortArray.sortArrayOf(fieldReference).by(sort);
|
||||
}
|
||||
|
||||
return (usesExpression() ? SortArray.sortArrayOf(expression) : SortArray.sortArray(values)).by(sort);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new {@link AggregationExpression} that transposes an array of input arrays so that the first element of
|
||||
* the output array would be an array containing, the first element of the first input array, the first element of
|
||||
@@ -1915,4 +1931,66 @@ public class ArrayOperators {
|
||||
return "$last";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link AggregationExpression} for {@code $sortArray} that sorts elements in an array. <br />
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 4.0
|
||||
*/
|
||||
public static class SortArray extends AbstractAggregationExpression {
|
||||
|
||||
private SortArray(Object value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given array.
|
||||
*
|
||||
* @param array must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArray(Object array) {
|
||||
return new SortArray(Collections.singletonMap("input", array));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the elements in the array pointed to by the given {@link Field field reference}.
|
||||
*
|
||||
* @param fieldReference must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArrayOf(String fieldReference) {
|
||||
return sortArray(Fields.field(fieldReference));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the elements of the array computed buy the given {@link AggregationExpression expression}.
|
||||
*
|
||||
* @param expression must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public static SortArray sortArrayOf(AggregationExpression expression) {
|
||||
return sortArray(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the order to put elements in.
|
||||
*
|
||||
* @param sort must not be {@literal null}.
|
||||
* @return new instance of {@link SortArray}.
|
||||
*/
|
||||
public SortArray by(Sort sort) {
|
||||
return new SortArray(append("sortBy", sort));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.AbstractAggregationExpression#getMongoMethod()
|
||||
*/
|
||||
@Override
|
||||
protected String getMongoMethod() {
|
||||
return "$sortArray";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,7 @@ public class MethodReferenceNode extends ExpressionNode {
|
||||
map.put("last", singleArgRef().forOperator("$last"));
|
||||
map.put("size", singleArgRef().forOperator("$size"));
|
||||
map.put("slice", arrayArgRef().forOperator("$slice"));
|
||||
map.put("sortArray", mapArgRef().forOperator("$sortArray").mappingParametersTo("input", "sortBy"));
|
||||
map.put("reverseArray", singleArgRef().forOperator("$reverseArray"));
|
||||
map.put("reduce", mapArgRef().forOperator("$reduce").mappingParametersTo("input", "initialValue", "in"));
|
||||
map.put("zip", mapArgRef().forOperator("$zip").mappingParametersTo("inputs", "useLongestLength", "defaults"));
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayToObject;
|
||||
|
||||
/**
|
||||
@@ -171,4 +172,11 @@ public class ArrayOperatorsUnitTests {
|
||||
assertThat(ArrayOperators.arrayOf("field").last().toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo("{ $last : \"$field\" }");
|
||||
}
|
||||
|
||||
@Test // GH-4139
|
||||
void sortByWithFieldRef() {
|
||||
|
||||
assertThat(ArrayOperators.arrayOf("team").sort(Sort.by("name")).toDocument(Aggregation.DEFAULT_CONTEXT))
|
||||
.isEqualTo("{ $sortArray: { input: \"$team\", sortBy: { name: 1 } } }");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,6 +1235,12 @@ public class SpelExpressionTransformerUnitTests {
|
||||
assertThat(transform("setField(\"score\", 100, source)")).isEqualTo("{ $setField : { field : \"score\", value : 100, input : \"$source\" }}");
|
||||
}
|
||||
|
||||
@Test // GH-4139
|
||||
void shouldRenderSortArray() {
|
||||
assertThat(transform(
|
||||
"sortArray(team, new org.bson.Document(\"name\" , 1))")).isEqualTo("{ $sortArray : { input : \"$team\", sortBy : {\"name\" : 1 } }}");
|
||||
}
|
||||
|
||||
private Document transform(String expression, Object... params) {
|
||||
return (Document) transformer.transform(expression, Aggregation.DEFAULT_CONTEXT, params);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user