DATAMONGO-1457 - Add support for $slice in aggregation.
We now support $slice in aggregation projections via the ProjectionOperationBuilder.
Aggregation.project().and("field").slice(10, 20)
Original pull request: #372.
This commit is contained in:
committed by
Mark Paluch
parent
f4a5482005
commit
9d51ea4c01
@@ -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. <br />
|
||||
* If {@literal n} is positive, $slice returns up to the first n elements in the array. <br />
|
||||
* 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. <br />
|
||||
*
|
||||
* @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)
|
||||
|
||||
@@ -1228,6 +1228,27 @@ public class AggregationTests {
|
||||
skip(100));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1457
|
||||
*/
|
||||
@Test
|
||||
public void sliceShouldBeAppliedCorrectly() {
|
||||
|
||||
assumeTrue(mongoVersion.isGreaterThanOrEqualTo(THREE_DOT_TWO));
|
||||
|
||||
createUserWithLikesDocuments();
|
||||
|
||||
TypedAggregation<UserWithLikes> agg = newAggregation(UserWithLikes.class, match(new Criteria()),
|
||||
project().and("likes").slice(2));
|
||||
|
||||
AggregationResults<UserWithLikes> 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);
|
||||
|
||||
@@ -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.<Object> asList("$field", 10))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1457
|
||||
*/
|
||||
@Test
|
||||
public void shouldRenderSliceWithPositionCorrectly() throws Exception {
|
||||
|
||||
ProjectionOperation operation = Aggregation.project().and("field").slice(10, 5).as("renamed");
|
||||
|
||||
DBObject dbObject = operation.toDBObject(Aggregation.DEFAULT_CONTEXT);
|
||||
DBObject projected = exctractOperation("$project", dbObject);
|
||||
|
||||
assertThat(projected.get("renamed"),
|
||||
is((Object) new BasicDBObject("$slice", Arrays.<Object> asList("$field", 5, 10))));
|
||||
}
|
||||
|
||||
private static DBObject exctractOperation(String field, DBObject fromProjectClause) {
|
||||
return (DBObject) fromProjectClause.get(field);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 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.
|
||||
@@ -20,9 +20,15 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class UserWithLikes {
|
||||
|
||||
String id;
|
||||
@@ -30,6 +36,7 @@ public class UserWithLikes {
|
||||
Set<String> likes = new HashSet<String>();
|
||||
|
||||
public UserWithLikes(String id, Date joined, String... likes) {
|
||||
|
||||
this.id = id;
|
||||
this.joined = joined;
|
||||
this.likes = new HashSet<String>(Arrays.asList(likes));
|
||||
|
||||
Reference in New Issue
Block a user