diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
index 68947352a..7d71cc1e1 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperation.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2015 the original author or authors.
+ * Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -352,6 +352,7 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
*
* @author Oliver Gierke
* @author Thomas Darimont
+ * @author Christoph Strobl
*/
public static class ProjectionOperationBuilder extends AbstractProjectionOperationBuilder {
@@ -566,6 +567,31 @@ public class ProjectionOperation implements FieldsExposingAggregationOperation {
return project("size");
}
+ /**
+ * Generates a {@code $slice} expression that returns a subset of the array held by the given field.
+ * If {@literal n} is positive, $slice returns up to the first n elements in the array.
+ * If {@literal n} is negative, $slice returns up to the last n elements in the array.
+ *
+ * @param count max number of elements.
+ * @return never {@literal null}.
+ * @since 1.10
+ */
+ public ProjectionOperationBuilder slice(int count) {
+ return project("slice", count);
+ }
+
+ /**
+ * Generates a {@code $slice} expression that returns a subset of the array held by the given field.
+ *
+ * @param count max number of elements. Must not be negative.
+ * @param offset the offset within the array to start from.
+ * @return never {@literal null}.
+ * @since 1.10
+ */
+ public ProjectionOperationBuilder slice(int count, int offset) {
+ return project("slice", offset, count);
+ }
+
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java
index 1de24d41b..b9ec9d853 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationTests.java
@@ -1228,6 +1228,27 @@ public class AggregationTests {
skip(100));
}
+ /**
+ * @see DATAMONGO-1457
+ */
+ @Test
+ public void sliceShouldBeAppliedCorrectly() {
+
+ assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
+
+ createUserWithLikesDocuments();
+
+ TypedAggregation agg = newAggregation(UserWithLikes.class, match(new Criteria()),
+ project().and("likes").slice(2));
+
+ AggregationResults result = mongoTemplate.aggregate(agg, UserWithLikes.class);
+
+ assertThat(result.getMappedResults(), hasSize(9));
+ for (UserWithLikes user : result) {
+ assertThat(user.likes.size() <= 2, is(true));
+ }
+ }
+
private void createUsersWithReferencedPersons() {
mongoTemplate.dropCollection(User.class);
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java
index 2f826ff93..bc1a06e51 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2015 the original author or authors.
+ * Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@ import com.mongodb.DBObject;
*
* @author Oliver Gierke
* @author Thomas Darimont
+ * @author Christoph Strobl
*/
public class ProjectionOperationUnitTests {
@@ -371,6 +372,36 @@ public class ProjectionOperationUnitTests {
assertThat(projected.get("tags_count"), is((Object) new BasicDBObject("$size", Arrays.asList("$tags"))));
}
+ /**
+ * @see DATAMONGO-1457
+ */
+ @Test
+ public void shouldRenderSliceCorrectly() throws Exception {
+
+ ProjectionOperation operation = Aggregation.project().and("field").slice(10).as("renamed");
+
+ DBObject dbObject = operation.toDBObject(Aggregation.DEFAULT_CONTEXT);
+ DBObject projected = exctractOperation("$project", dbObject);
+
+ assertThat(projected.get("renamed"),
+ is((Object) new BasicDBObject("$slice", Arrays.