Browse Source

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
pull/4878/head
Christoph Strobl 1 year ago committed by Mark Paluch
parent
commit
d8700261db
No known key found for this signature in database
GPG Key ID: 55BC6374BAA9D973
  1. 55
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java
  2. 12
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java

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

@ -1032,35 +1032,68 @@ public class ArrayOperators { @@ -1032,35 +1032,68 @@ public class ArrayOperators {
return new Slice(append(nrElements));
}
/**
* Slice the number of elements.
*
* @param nrElements An {@link AggregationExpression} that evaluates to a numeric value used as item count.
* @return new instance of {@link Slice}.
* @since 4.5
*/
public Slice itemCount(AggregationExpression nrElements) {
return new Slice(append(nrElements));
}
/**
* Slice using offset and count.
*
* @param position the start position
* @return new instance of {@link SliceElementsBuilder} to create {@link Slice}.
*/
public SliceElementsBuilder offset(final int position) {
return new SliceElementsBuilder() {
public SliceElementsBuilder offset(int position) {
return new SliceElementsBuilder(position);
}
@Override
public Slice itemCount(int nrElements) {
return new Slice(append(position)).itemCount(nrElements);
}
};
/**
* Slice using offset and count.
*
* @param position the start position
* @return new instance of {@link SliceElementsBuilder} to create {@link Slice}.
*/
public SliceElementsBuilder offset(AggregationExpression position) {
return new SliceElementsBuilder(position);
}
/**
* @author Christoph Strobl
*/
public interface SliceElementsBuilder {
public class SliceElementsBuilder {
private final Object position;
SliceElementsBuilder(Object position) {
this.position = position;
}
/**
* Set the number of elements given {@literal nrElements}.
*
* @param nrElements
* @return
* @return new instance of {@link Slice}.
*/
Slice itemCount(int nrElements);
public Slice itemCount(int nrElements) {
return new Slice(append(position)).itemCount(nrElements);
}
/**
* Slice the number of elements.
*
* @param nrElements An {@link AggregationExpression} that evaluates to a numeric value used as item count.
* @return new instance of {@link Slice}.
* @since 4.5
*/
public Slice itemCount(AggregationExpression nrElements) {
return new Slice(append(position)).itemCount(nrElements);
}
}
}

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

@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test; @@ -29,6 +29,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound;
import org.springframework.data.mongodb.core.DocumentTestUtils;
import org.springframework.data.mongodb.core.aggregation.ArithmeticOperators.Subtract;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.Variable;
@ -1064,6 +1065,17 @@ public class ProjectionOperationUnitTests { @@ -1064,6 +1065,17 @@ public class ProjectionOperationUnitTests {
assertThat(agg).isEqualTo(Document.parse("{ $project: { threeFavorites: { $slice: [ \"$favorites\", 2, 3 ] } } }"));
}
@Test // DATAMONGO-4857
void shouldRenderSliceWithExpressions() {
Document agg = project().and(ArrayOperators.arrayOf("favorites").slice()
.offset(Subtract.valueOf(ArrayOperators.Size.lengthOfArray("myArray")).subtract(1))
.itemCount(ArithmeticOperators.rand())).as("threeFavorites").toDocument(Aggregation.DEFAULT_CONTEXT);
assertThat(agg).isEqualTo(Document.parse(
"{ $project: { threeFavorites: { $slice: [ \"$favorites\", { \"$subtract\": [ {\"$size\": \"$myArray\"}, 1]}, { $rand : {} } ] } } }"));
}
@Test // DATAMONGO-1536
void shouldRenderLiteral() {

Loading…
Cancel
Save