DATAMONGO-1391 - Support Mongo 3.2 syntax for $unwind in aggregation.
We now support both, the simple {$unwind: path} and the MongoDB 3.2 {$unwind: {…}} syntax.
Original Pull Request: #355
This commit is contained in:
committed by
Christoph Strobl
parent
0dd904894d
commit
f8681fec66
@@ -195,13 +195,56 @@ public class Aggregation {
|
||||
/**
|
||||
* Factory method to create a new {@link UnwindOperation} for the field with the given name.
|
||||
*
|
||||
* @param fieldName must not be {@literal null} or empty.
|
||||
* @param field must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
public static UnwindOperation unwind(String field) {
|
||||
return new UnwindOperation(field(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link UnwindOperation} for the field with the given name and
|
||||
* {@code preserveNullAndEmptyArrays}. Note that extended unwind is supported in MongoDB version 3.2+.
|
||||
*
|
||||
* @param field must not be {@literal null} or empty.
|
||||
* @param preserveNullAndEmptyArrays {@literal true} to output the document if path is {@literal null}, missing or
|
||||
* array is empty.
|
||||
* @return
|
||||
* @since 1.10
|
||||
*/
|
||||
public static UnwindOperation unwind(String field, boolean preserveNullAndEmptyArrays) {
|
||||
return new UnwindOperation(field(field), preserveNullAndEmptyArrays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link UnwindOperation} for the field with the given name and to include the index
|
||||
* field as {@code arrayIndex}. Note that extended unwind is supported in MongoDB version 3.2+.
|
||||
*
|
||||
* @param field must not be {@literal null} or empty.
|
||||
* @param arrayIndex must not be {@literal null} or empty.
|
||||
* @return
|
||||
* @since 1.10
|
||||
*/
|
||||
public static UnwindOperation unwind(String field, String arrayIndex) {
|
||||
return new UnwindOperation(field(field), field(arrayIndex), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method to create a new {@link UnwindOperation} for the field with the given name, to include the index
|
||||
* field as {@code arrayIndex} and {@code preserveNullAndEmptyArrays}. Note that extended unwind is supported in
|
||||
* MongoDB version 3.2+.
|
||||
*
|
||||
* @param field must not be {@literal null} or empty.
|
||||
* @param arrayIndex must not be {@literal null} or empty.
|
||||
* @param preserveNullAndEmptyArrays {@literal true} to output the document if path is {@literal null}, missing or
|
||||
* array is empty.
|
||||
* @return
|
||||
* @since 1.10
|
||||
*/
|
||||
public static UnwindOperation unwind(String field, String arrayIndex, boolean preserveNullAndEmptyArrays) {
|
||||
return new UnwindOperation(field(field), field(arrayIndex), preserveNullAndEmptyArrays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link GroupOperation} for the given fields.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2014 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.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.util.CompositeIterator;
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Mark Paluch
|
||||
* @since 1.3
|
||||
*/
|
||||
public final class ExposedFields implements Iterable<ExposedField> {
|
||||
@@ -203,8 +204,13 @@ public final class ExposedFields implements Iterable<ExposedField> {
|
||||
public Iterator<ExposedField> iterator() {
|
||||
|
||||
CompositeIterator<ExposedField> iterator = new CompositeIterator<ExposedField>();
|
||||
iterator.add(syntheticFields.iterator());
|
||||
iterator.add(originalFields.iterator());
|
||||
if (!syntheticFields.isEmpty()) {
|
||||
iterator.add(syntheticFields.iterator());
|
||||
}
|
||||
|
||||
if (!originalFields.isEmpty()) {
|
||||
iterator.add(originalFields.iterator());
|
||||
}
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -19,6 +19,7 @@ import org.springframework.data.mongodb.core.aggregation.ExposedFields.ExposedFi
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.BasicDBObjectBuilder;
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
@@ -30,11 +31,15 @@ import com.mongodb.DBObject;
|
||||
* @see http://docs.mongodb.org/manual/reference/aggregation/unwind/#pipe._S_unwind
|
||||
* @author Thomas Darimont
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @since 1.3
|
||||
*/
|
||||
public class UnwindOperation implements AggregationOperation {
|
||||
public class UnwindOperation
|
||||
implements AggregationOperation, FieldsExposingAggregationOperation.InheritsFieldsAggregationOperation {
|
||||
|
||||
private final ExposedField field;
|
||||
private final ExposedField arrayIndex;
|
||||
private final boolean preserveNullAndEmptyArrays;
|
||||
|
||||
/**
|
||||
* Creates a new {@link UnwindOperation} for the given {@link Field}.
|
||||
@@ -42,17 +47,191 @@ public class UnwindOperation implements AggregationOperation {
|
||||
* @param field must not be {@literal null}.
|
||||
*/
|
||||
public UnwindOperation(Field field) {
|
||||
|
||||
Assert.notNull(field);
|
||||
this.field = new ExposedField(field, true);
|
||||
this(new ExposedField(field, true), false);
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Creates a new {@link UnwindOperation} using Mongo 3.2 syntax.
|
||||
*
|
||||
* @param field must not be {@literal null}.
|
||||
* @param preserveNullAndEmptyArrays {@literal true} to output the document if path is {@literal null}, missing or
|
||||
* array is empty.
|
||||
* @since 1.10
|
||||
*/
|
||||
public UnwindOperation(Field field, boolean preserveNullAndEmptyArrays) {
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
|
||||
this.field = new ExposedField(field, true);
|
||||
this.arrayIndex = null;
|
||||
this.preserveNullAndEmptyArrays = preserveNullAndEmptyArrays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link UnwindOperation} using Mongo 3.2 syntax.
|
||||
*
|
||||
* @param field must not be {@literal null}.
|
||||
* @param arrayIndex optional field name to expose the field array index, must not be {@literal null}.
|
||||
* @param preserveNullAndEmptyArrays {@literal true} to output the document if path is {@literal null}, missing or
|
||||
* array is empty.
|
||||
* @since 1.10
|
||||
*/
|
||||
public UnwindOperation(Field field, Field arrayIndex, boolean preserveNullAndEmptyArrays) {
|
||||
|
||||
Assert.notNull(field, "Field must not be null!");
|
||||
Assert.notNull(arrayIndex, "ArrayIndex must not be null!");
|
||||
|
||||
this.field = new ExposedField(field, true);
|
||||
this.arrayIndex = new ExposedField(arrayIndex, true);
|
||||
this.preserveNullAndEmptyArrays = preserveNullAndEmptyArrays;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.aggregation.AggregationOperation#toDBObject(org.springframework.data.mongodb.core.aggregation.AggregationOperationContext)
|
||||
*/
|
||||
@Override
|
||||
public DBObject toDBObject(AggregationOperationContext context) {
|
||||
return new BasicDBObject("$unwind", context.getReference(field).toString());
|
||||
|
||||
String unwindField = context.getReference(field).toString();
|
||||
Object unwindArg;
|
||||
|
||||
if (preserveNullAndEmptyArrays || arrayIndex != null) {
|
||||
|
||||
BasicDBObjectBuilder builder = BasicDBObjectBuilder.start().add("path", unwindField);
|
||||
builder.add("preserveNullAndEmptyArrays", preserveNullAndEmptyArrays);
|
||||
|
||||
if (arrayIndex != null) {
|
||||
builder.add("includeArrayIndex", arrayIndex.getName());
|
||||
}
|
||||
|
||||
unwindArg = builder.get();
|
||||
} else {
|
||||
unwindArg = unwindField;
|
||||
}
|
||||
|
||||
return new BasicDBObject("$unwind", unwindArg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExposedFields getFields() {
|
||||
return arrayIndex != null ? ExposedFields.from(arrayIndex) : ExposedFields.from();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a builder that allows creation of {@link LookupOperation}.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static PathBuilder newUnwind() {
|
||||
return UnwindOperationBuilder.newBuilder();
|
||||
}
|
||||
|
||||
public static interface PathBuilder {
|
||||
|
||||
/**
|
||||
* @param path the path to unwind, must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
IndexBuilder path(String path);
|
||||
}
|
||||
|
||||
public static interface IndexBuilder {
|
||||
|
||||
/**
|
||||
* Exposes the array index as {@code field}.
|
||||
*
|
||||
* @param field field name to expose the field array index, must not be {@literal null} or empty.
|
||||
* @return
|
||||
*/
|
||||
EmptyArraysBuilder arrayIndex(String field);
|
||||
|
||||
/**
|
||||
* Do not expose the array index.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
EmptyArraysBuilder noArrayIndex();
|
||||
}
|
||||
|
||||
public static interface EmptyArraysBuilder {
|
||||
|
||||
/**
|
||||
* Output documents if the array is null or empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UnwindOperation preserveNullAndEmptyArrays();
|
||||
|
||||
/**
|
||||
* Do not output documents if the array is null or empty.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
UnwindOperation skipNullAndEmptyArrays();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for fluent {@link UnwindOperation} creation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 1.10
|
||||
*/
|
||||
public static final class UnwindOperationBuilder implements PathBuilder, IndexBuilder, EmptyArraysBuilder {
|
||||
|
||||
private Field field;
|
||||
private Field arrayIndex;
|
||||
|
||||
private UnwindOperationBuilder() {}
|
||||
|
||||
/**
|
||||
* Creates new builder for {@link UnwindOperation}.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
public static PathBuilder newBuilder() {
|
||||
return new UnwindOperationBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnwindOperation preserveNullAndEmptyArrays() {
|
||||
|
||||
if (arrayIndex != null) {
|
||||
return new UnwindOperation(field, arrayIndex, true);
|
||||
}
|
||||
|
||||
return new UnwindOperation(field, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnwindOperation skipNullAndEmptyArrays() {
|
||||
|
||||
if (arrayIndex != null) {
|
||||
return new UnwindOperation(field, arrayIndex, false);
|
||||
}
|
||||
|
||||
return new UnwindOperation(field, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmptyArraysBuilder arrayIndex(String field) {
|
||||
Assert.hasText(field, "'ArrayIndex' must not be null or empty!");
|
||||
arrayIndex = Fields.field(field);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmptyArraysBuilder noArrayIndex() {
|
||||
arrayIndex = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnwindOperationBuilder path(String path) {
|
||||
Assert.hasText(path, "'Path' must not be null or empty!");
|
||||
field = Fields.field(path);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -241,6 +241,64 @@ public class AggregationTests {
|
||||
assertThat(tagCount.size(), is(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void shouldUnwindWithIndex() {
|
||||
|
||||
DBCollection coll = mongoTemplate.getCollection(INPUT_COLLECTION);
|
||||
|
||||
coll.insert(createDocument("Doc1", "spring", "mongodb", "nosql"));
|
||||
coll.insert(createDocument("Doc2"));
|
||||
|
||||
Aggregation agg = newAggregation( //
|
||||
project("tags"), //
|
||||
unwind("tags", "n"), //
|
||||
project("n") //
|
||||
.and("tag").previousOperation(), //
|
||||
sort(DESC, "n") //
|
||||
);
|
||||
|
||||
AggregationResults<TagCount> results = mongoTemplate.aggregate(agg, INPUT_COLLECTION, TagCount.class);
|
||||
|
||||
assertThat(results, is(notNullValue()));
|
||||
|
||||
List<TagCount> tagCount = results.getMappedResults();
|
||||
|
||||
assertThat(tagCount, is(notNullValue()));
|
||||
assertThat(tagCount.size(), is(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void shouldUnwindPreserveEmpty() {
|
||||
|
||||
DBCollection coll = mongoTemplate.getCollection(INPUT_COLLECTION);
|
||||
|
||||
coll.insert(createDocument("Doc1", "spring", "mongodb", "nosql"));
|
||||
coll.insert(createDocument("Doc2"));
|
||||
|
||||
Aggregation agg = newAggregation( //
|
||||
project("tags"), //
|
||||
unwind("tags", "n", true), //
|
||||
sort(DESC, "n") //
|
||||
);
|
||||
|
||||
AggregationResults<DBObject> results = mongoTemplate.aggregate(agg, INPUT_COLLECTION, DBObject.class);
|
||||
|
||||
assertThat(results, is(notNullValue()));
|
||||
|
||||
List<DBObject> tagCount = results.getMappedResults();
|
||||
|
||||
assertThat(tagCount, is(notNullValue()));
|
||||
assertThat(tagCount.size(), is(4));
|
||||
assertThat(tagCount.get(0), isBsonObject().containing("n", 2L));
|
||||
assertThat(tagCount.get(3), isBsonObject().notContaining("n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDetectResultMismatch() {
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -20,6 +20,7 @@ import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.core.DBObjectTestUtils.*;
|
||||
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
|
||||
import static org.springframework.data.mongodb.core.query.Criteria.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -39,6 +40,7 @@ import com.mongodb.DBObject;
|
||||
* @author Oliver Gierke
|
||||
* @author Thomas Darimont
|
||||
* @author Christoph Strobl
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class AggregationUnitTests {
|
||||
|
||||
@@ -94,6 +96,64 @@ public class AggregationUnitTests {
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindOperationWithIndexShouldPreserveFields() {
|
||||
|
||||
newAggregation( //
|
||||
project("a", "b"), //
|
||||
unwind("a", "x"), //
|
||||
project("a", "b") // b should still be available
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindOperationWithIndexShouldAddIndexField() {
|
||||
|
||||
newAggregation( //
|
||||
project("a", "b"), //
|
||||
unwind("a", "x"), //
|
||||
project("a", "x") // b should still be available
|
||||
).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void fullUnwindOperationShouldBuildCorrectClause() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
unwind("a", "x", true)).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject unwind = ((List<DBObject>) agg.get("pipeline")).get(0);
|
||||
assertThat((DBObject) unwind.get("$unwind"),
|
||||
isBsonObject(). //
|
||||
containing("includeArrayIndex", "x").//
|
||||
containing("preserveNullAndEmptyArrays", true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindOperationWithPreserveNullShouldBuildCorrectClause() {
|
||||
|
||||
DBObject agg = newAggregation( //
|
||||
unwind("a", true)).toDbObject("foo", Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
DBObject unwind = ((List<DBObject>) agg.get("pipeline")).get(0);
|
||||
assertThat(unwind,
|
||||
isBsonObject().notContaining("includeArrayIndex").containing("preserveNullAndEmptyArrays", true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-753
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* 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.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.data.mongodb.test.util.IsBsonObject.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.mongodb.core.DBObjectTestUtils;
|
||||
|
||||
import com.mongodb.DBObject;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link UnwindOperation}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class UnwindOperationUnitTests {
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindWithPathOnlyShouldUsePreMongo32Syntax() {
|
||||
|
||||
UnwindOperation unwindOperation = Aggregation.unwind("a");
|
||||
|
||||
DBObject pipeline = unwindOperation.toDBObject(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(pipeline, isBsonObject().containing("$unwind", "$a"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindWithArrayIndexShouldUseMongo32Syntax() {
|
||||
|
||||
UnwindOperation unwindOperation = Aggregation.unwind("a", "index");
|
||||
|
||||
DBObject unwindClause = extractDbObjectFromUnwindOperation(unwindOperation);
|
||||
|
||||
assertThat(unwindClause,
|
||||
isBsonObject().containing("path", "$a").//
|
||||
containing("preserveNullAndEmptyArrays", false).//
|
||||
containing("includeArrayIndex", "index"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindWithArrayIndexShouldExposeArrayIndex() {
|
||||
|
||||
UnwindOperation unwindOperation = Aggregation.unwind("a", "index");
|
||||
|
||||
assertThat(unwindOperation.getFields().getField("index"), is(not(nullValue())));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void plainUnwindShouldNotExposeIndex() {
|
||||
|
||||
UnwindOperation unwindOperation = Aggregation.unwind("a");
|
||||
|
||||
assertThat(unwindOperation.getFields().exposesNoFields(), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void unwindWithPreserveNullShouldUseMongo32Syntax() {
|
||||
|
||||
UnwindOperation unwindOperation = Aggregation.unwind("a", true);
|
||||
|
||||
DBObject unwindClause = extractDbObjectFromUnwindOperation(unwindOperation);
|
||||
|
||||
assertThat(unwindClause,
|
||||
isBsonObject().containing("path", "$a").//
|
||||
containing("preserveNullAndEmptyArrays", true).//
|
||||
notContaining("includeArrayIndex"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void lookupBuilderBuildsCorrectClause() {
|
||||
|
||||
UnwindOperation unwindOperation = UnwindOperation.newUnwind().path("$foo").noArrayIndex().skipNullAndEmptyArrays();
|
||||
DBObject pipeline = unwindOperation.toDBObject(Aggregation.DEFAULT_CONTEXT);
|
||||
|
||||
assertThat(pipeline, isBsonObject().containing("$unwind", "$foo"));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-1391
|
||||
*/
|
||||
@Test
|
||||
public void lookupBuilderBuildsCorrectClauseForMongo32() {
|
||||
|
||||
UnwindOperation unwindOperation = UnwindOperation.newUnwind().path("$foo").arrayIndex("myindex")
|
||||
.preserveNullAndEmptyArrays();
|
||||
|
||||
DBObject unwindClause = extractDbObjectFromUnwindOperation(unwindOperation);
|
||||
|
||||
assertThat(unwindClause,
|
||||
isBsonObject().containing("path", "$foo").//
|
||||
containing("preserveNullAndEmptyArrays", true).//
|
||||
notContaining("myindex"));
|
||||
}
|
||||
|
||||
private DBObject extractDbObjectFromUnwindOperation(UnwindOperation unwindOperation) {
|
||||
|
||||
DBObject dbObject = unwindOperation.toDBObject(Aggregation.DEFAULT_CONTEXT);
|
||||
DBObject unwindClause = DBObjectTestUtils.getAsDBObject(dbObject, "$unwind");
|
||||
return unwindClause;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user