Skip to content

Commit

Permalink
Support Expressions in $slice operator.
Browse files Browse the repository at this point in the history
This commit allows AggregationExpressions to be used for itemCount and offset of the Slice expression.
  • Loading branch information
christophstrobl committed Dec 18, 2024
1 parent 633338a commit ea28713
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1032,35 +1032,68 @@ public Slice itemCount(int 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.
*
* @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);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
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;
Expand Down Expand Up @@ -1064,6 +1065,17 @@ void shouldRenderSliceWithPositionAggregationExpression() {
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() {

Expand Down

0 comments on commit ea28713

Please sign in to comment.