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 {
return new Slice(append(nrElements)); 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. * Slice using offset and count.
* *
* @param position the start position * @param position the start position
* @return new instance of {@link SliceElementsBuilder} to create {@link Slice}. * @return new instance of {@link SliceElementsBuilder} to create {@link Slice}.
*/ */
public SliceElementsBuilder offset(final int position) { public SliceElementsBuilder offset(int position) {
return new SliceElementsBuilder(position);
return new SliceElementsBuilder() { }
@Override /**
public Slice itemCount(int nrElements) { * Slice using offset and count.
return new Slice(append(position)).itemCount(nrElements); *
} * @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 * @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}. * Set the number of elements given {@literal nrElements}.
* *
* @param 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;
import org.springframework.data.domain.Range; import org.springframework.data.domain.Range;
import org.springframework.data.domain.Range.Bound; import org.springframework.data.domain.Range.Bound;
import org.springframework.data.mongodb.core.DocumentTestUtils; 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;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.Variable; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.Variable;
@ -1064,6 +1065,17 @@ public class ProjectionOperationUnitTests {
assertThat(agg).isEqualTo(Document.parse("{ $project: { threeFavorites: { $slice: [ \"$favorites\", 2, 3 ] } } }")); 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 @Test // DATAMONGO-1536
void shouldRenderLiteral() { void shouldRenderLiteral() {

Loading…
Cancel
Save