diff --git a/pom.xml b/pom.xml
index 1d9b760700..a3e8541a78 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
pom
Spring Data MongoDB
diff --git a/spring-data-mongodb-cross-store/pom.xml b/spring-data-mongodb-cross-store/pom.xml
index fd36debedd..4b5a6c0e7c 100644
--- a/spring-data-mongodb-cross-store/pom.xml
+++ b/spring-data-mongodb-cross-store/pom.xml
@@ -6,7 +6,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
../pom.xml
@@ -48,7 +48,7 @@
org.springframework.data
spring-data-mongodb
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
diff --git a/spring-data-mongodb-distribution/pom.xml b/spring-data-mongodb-distribution/pom.xml
index 28c91bc332..2e0a228213 100644
--- a/spring-data-mongodb-distribution/pom.xml
+++ b/spring-data-mongodb-distribution/pom.xml
@@ -13,7 +13,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb-log4j/pom.xml b/spring-data-mongodb-log4j/pom.xml
index dfe146ff96..5d55ebdd76 100644
--- a/spring-data-mongodb-log4j/pom.xml
+++ b/spring-data-mongodb-log4j/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/pom.xml b/spring-data-mongodb/pom.xml
index 0fcdb2f39f..762974d85c 100644
--- a/spring-data-mongodb/pom.xml
+++ b/spring-data-mongodb/pom.xml
@@ -11,7 +11,7 @@
org.springframework.data
spring-data-mongodb-parent
- 1.9.0.BUILD-SNAPSHOT
+ 1.9.0.DATAMONGO-1391-SNAPSHOT
../pom.xml
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java
index 1c98ebd315..f1be24bd3c 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/Aggregation.java
@@ -195,13 +195,56 @@ public static ProjectionOperation project(Fields fields) {
/**
* 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.
*
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java
index 79bece0f85..02537fcbd7 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ExposedFields.java
@@ -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 @@
*
* @author Oliver Gierke
* @author Thomas Darimont
+ * @author Mark Paluch
* @since 1.3
*/
public final class ExposedFields implements Iterable {
@@ -203,8 +204,13 @@ private int exposedFieldsCount() {
public Iterator iterator() {
CompositeIterator iterator = new CompositeIterator();
- iterator.add(syntheticFields.iterator());
- iterator.add(originalFields.iterator());
+ if (!syntheticFields.isEmpty()) {
+ iterator.add(syntheticFields.iterator());
+ }
+
+ if (!originalFields.isEmpty()) {
+ iterator.add(originalFields.iterator());
+ }
return iterator;
}
diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java
index 883cb8a8c4..3f62d4c079 100644
--- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.java
+++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/UnwindOperation.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.
@@ -19,6 +19,7 @@
import org.springframework.util.Assert;
import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
import com.mongodb.DBObject;
/**
@@ -30,11 +31,15 @@
* @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) {
+ 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!");
- Assert.notNull(field);
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;
+ }
+
+ }
+
}
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 7a23b03782..4dc5306ad9 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
@@ -241,6 +241,64 @@ public void shouldAggregateEmptyCollection() {
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 results = mongoTemplate.aggregate(agg, INPUT_COLLECTION, TagCount.class);
+
+ assertThat(results, is(notNullValue()));
+
+ List 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 results = mongoTemplate.aggregate(agg, INPUT_COLLECTION, DBObject.class);
+
+ assertThat(results, is(notNullValue()));
+
+ List 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() {
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java
index 7c8d3d3dbd..03387417c2 100644
--- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.java
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/AggregationUnitTests.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.
@@ -20,6 +20,7 @@
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 @@
* @author Oliver Gierke
* @author Thomas Darimont
* @author Christoph Strobl
+ * @author Mark Paluch
*/
public class AggregationUnitTests {
@@ -94,6 +96,64 @@ public void unwindOperationShouldNotChangeAvailableFields() {
).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) 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) agg.get("pipeline")).get(0);
+ assertThat(unwind,
+ isBsonObject().notContaining("includeArrayIndex").containing("preserveNullAndEmptyArrays", true));
+ }
+
/**
* @see DATAMONGO-753
*/
diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnwindOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnwindOperationUnitTests.java
new file mode 100644
index 0000000000..4ebb01a3db
--- /dev/null
+++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/UnwindOperationUnitTests.java
@@ -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;
+ }
+}