DATAMONGO-1325 - Add $sample aggregation stage.
We now support the $sample aggregation pipeline stage via Aggregation to select a random subset of result documents. TypedAggregation<Employee> agg = Aggregation.newAggregation(Employee.class, sample(5)); Original pull request: #452.
This commit is contained in:
committed by
Mark Paluch
parent
7bfbff0602
commit
d40084f78e
@@ -51,6 +51,7 @@ import org.springframework.util.Assert;
|
||||
* @author Alessio Fachechi
|
||||
* @author Christoph Strobl
|
||||
* @author Nikolay Bogdanov
|
||||
* @author Gustavo de Geus
|
||||
* @since 1.3
|
||||
*/
|
||||
public class Aggregation {
|
||||
@@ -382,6 +383,16 @@ public class Aggregation {
|
||||
return new LimitOperation(maxElements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SampleOperation} to selects the specified number of documents from its input randomly.
|
||||
*
|
||||
* @param sampleSize must not be less than zero.
|
||||
* @return
|
||||
*/
|
||||
public static SampleOperation sample(long sampleSize) {
|
||||
return new SampleOperation(sampleSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link MatchOperation} using the given {@link Criteria}.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Encapsulates the {@code $sample}-operation.
|
||||
* <p>
|
||||
* We recommend to use the static factory method {@link Aggregation#sample(long)} instead of creating instances of this
|
||||
* class directly.
|
||||
*
|
||||
* @author Gustavo de Geus
|
||||
* @since 2.0
|
||||
* @see <a href="https://docs.mongodb.com/master/reference/operator/aggregation/sample/">MongoDB Aggregation Framework: $sample</a>
|
||||
*/
|
||||
public class SampleOperation implements AggregationOperation {
|
||||
|
||||
private final long sampleSize;
|
||||
|
||||
/**
|
||||
* @param sampleSize number of documents to be randomly selected from its input.
|
||||
*/
|
||||
public SampleOperation(long sampleSize) {
|
||||
|
||||
Assert.isTrue(sampleSize > 0, "Sample size must be greater than zero!");
|
||||
this.sampleSize = sampleSize;
|
||||
}
|
||||
|
||||
/*
|
||||
(non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.BucketOperationSupport#toDocument(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
|
||||
*/
|
||||
@Override
|
||||
public Document toDocument(AggregationOperationContext context) {
|
||||
return new Document("$sample", new Document("size", this.sampleSize));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.aggregation;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link SampleOperation}.
|
||||
*
|
||||
* @author Gustavo de Geus
|
||||
*/
|
||||
public class SampleOperationUnitTests {
|
||||
|
||||
private static final String SIZE = "size";
|
||||
private static final String OP = "$sample";
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNegativeSample() {
|
||||
new SampleOperation(-1L);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsZeroSample() {
|
||||
new SampleOperation(0L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rendersSampleOperation() {
|
||||
long sampleSize = 5L;
|
||||
SampleOperation sampleOperation = Aggregation.sample(sampleSize);
|
||||
Document sampleOperationDocument = sampleOperation.toDocument(Aggregation.DEFAULT_CONTEXT);
|
||||
assertNotNull(sampleOperationDocument.get(OP));
|
||||
assertThat(sampleOperationDocument.get(OP), is(instanceOf(Document.class)));
|
||||
Document sampleSizeDocument = sampleOperationDocument.get(OP, Document.class);
|
||||
assertEquals(sampleSize, sampleSizeDocument.get(SIZE));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user