Skip to content

Commit d870026

Browse files
christophstroblmp911de
authored andcommitted
Support Expressions in $slice operator.
This commit allows AggregationExpressions to be used for itemCount and offset of the Slice expression. Original pull request: #4858 Closes #4857
1 parent a113240 commit d870026

File tree

2 files changed

+56
-11
lines changed

2 files changed

+56
-11
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java

+44-11
Original file line numberDiff line numberDiff line change
@@ -1032,35 +1032,68 @@ public Slice itemCount(int nrElements) {
10321032
return new Slice(append(nrElements));
10331033
}
10341034

1035+
/**
1036+
* Slice the number of elements.
1037+
*
1038+
* @param nrElements An {@link AggregationExpression} that evaluates to a numeric value used as item count.
1039+
* @return new instance of {@link Slice}.
1040+
* @since 4.5
1041+
*/
1042+
public Slice itemCount(AggregationExpression nrElements) {
1043+
return new Slice(append(nrElements));
1044+
}
1045+
10351046
/**
10361047
* Slice using offset and count.
10371048
*
10381049
* @param position the start position
10391050
* @return new instance of {@link SliceElementsBuilder} to create {@link Slice}.
10401051
*/
1041-
public SliceElementsBuilder offset(final int position) {
1042-
1043-
return new SliceElementsBuilder() {
1052+
public SliceElementsBuilder offset(int position) {
1053+
return new SliceElementsBuilder(position);
1054+
}
10441055

1045-
@Override
1046-
public Slice itemCount(int nrElements) {
1047-
return new Slice(append(position)).itemCount(nrElements);
1048-
}
1049-
};
1056+
/**
1057+
* Slice using offset and count.
1058+
*
1059+
* @param position the start position
1060+
* @return new instance of {@link SliceElementsBuilder} to create {@link Slice}.
1061+
*/
1062+
public SliceElementsBuilder offset(AggregationExpression position) {
1063+
return new SliceElementsBuilder(position);
10501064
}
10511065

10521066
/**
10531067
* @author Christoph Strobl
10541068
*/
1055-
public interface SliceElementsBuilder {
1069+
public class SliceElementsBuilder {
1070+
1071+
private final Object position;
1072+
1073+
SliceElementsBuilder(Object position) {
1074+
this.position = position;
1075+
}
10561076

10571077
/**
10581078
* Set the number of elements given {@literal nrElements}.
10591079
*
10601080
* @param nrElements
1061-
* @return
1081+
* @return new instance of {@link Slice}.
10621082
*/
1063-
Slice itemCount(int nrElements);
1083+
public Slice itemCount(int nrElements) {
1084+
return new Slice(append(position)).itemCount(nrElements);
1085+
}
1086+
1087+
/**
1088+
* Slice the number of elements.
1089+
*
1090+
* @param nrElements An {@link AggregationExpression} that evaluates to a numeric value used as item count.
1091+
* @return new instance of {@link Slice}.
1092+
* @since 4.5
1093+
*/
1094+
public Slice itemCount(AggregationExpression nrElements) {
1095+
return new Slice(append(position)).itemCount(nrElements);
1096+
}
10641097
}
10651098
}
10661099

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java

+12
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.springframework.data.domain.Range;
3030
import org.springframework.data.domain.Range.Bound;
3131
import org.springframework.data.mongodb.core.DocumentTestUtils;
32+
import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.Subtract;
3233
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce;
3334
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression;
3435
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.Variable;
@@ -1064,6 +1065,17 @@ void shouldRenderSliceWithPositionAggregationExpression() {
10641065
assertThat(agg).isEqualTo(Document.parse("{ $project: { threeFavorites: { $slice: [ \"$favorites\", 2, 3 ] } } }"));
10651066
}
10661067

1068+
@Test // DATAMONGO-4857
1069+
void shouldRenderSliceWithExpressions() {
1070+
1071+
Document agg = project().and(ArrayOperators.arrayOf("favorites").slice()
1072+
.offset(Subtract.valueOf(ArrayOperators.Size.lengthOfArray("myArray")).subtract(1))
1073+
.itemCount(ArithmeticOperators.rand())).as("threeFavorites").toDocument(Aggregation.DEFAULT_CONTEXT);
1074+
1075+
assertThat(agg).isEqualTo(Document.parse(
1076+
"{ $project: { threeFavorites: { $slice: [ \"$favorites\", { \"$subtract\": [ {\"$size\": \"$myArray\"}, 1]}, { $rand : {} } ] } } }"));
1077+
}
1078+
10671079
@Test // DATAMONGO-1536
10681080
void shouldRenderLiteral() {
10691081

0 commit comments

Comments
 (0)