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 1b3b00f28..acea5e03b 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 @@ -64,6 +64,33 @@ public class Aggregation { */ public static final String CURRENT = SystemVariable.CURRENT.toString(); + /** + * A variable which evaluates to the missing value. Allows for the conditional exclusion of fields. In a + * {@code $projection}, a field set to the variable {@literal REMOVE} is excluded from the output. + * + *
+ *
+ *
+ * db.books.aggregate( [
+ * {
+ * $project: {
+ * title: 1,
+ * "author.first": 1,
+ * "author.last" : 1,
+ * "author.middle": {
+ * $cond: {
+ * if: { $eq: [ "", "$author.middle" ] },
+ * then: "$$REMOVE",
+ * else: "$author.middle"
+ * }
+ * }
+ * }
+ * } ] )
+ *
+ *
+ */
+ public static final String REMOVE = SystemVariable.REMOVE.toString();
+
public static final AggregationOperationContext DEFAULT_CONTEXT = AggregationOperationRenderer.DEFAULT_CONTEXT;
public static final AggregationOptions DEFAULT_OPTIONS = newAggregationOptions().build();
@@ -648,11 +675,12 @@ public class Aggregation {
* Describes the system variables available in MongoDB aggregation framework pipeline expressions.
*
* @author Thomas Darimont
- * @see Aggregation Variables
+ * @author Christoph Strobl
+ * @see Aggregation Variables.
*/
enum SystemVariable {
- ROOT, CURRENT;
+ ROOT, CURRENT, REMOVE;
private static final String PREFIX = "$$";
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 3baa77495..dec24890c 100755
--- 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
@@ -21,6 +21,8 @@ import static org.springframework.data.mongodb.core.aggregation.Fields.*;
import static org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable.*;
import static org.springframework.data.mongodb.test.util.Assertions.*;
+import lombok.Data;
+
import java.util.Arrays;
import java.util.List;
@@ -212,6 +214,21 @@ public class ProjectionOperationUnitTests {
assertThat((Integer) projectClause.get(Fields.UNDERSCORE_ID)).isEqualTo(0);
}
+ @Test // DATAMONGO-1906
+ public void rendersConditionalProjectionCorrectly() {
+
+ TypedAggregation aggregation = Aggregation.newAggregation(Book.class,
+ Aggregation.project("title")
+ .and(ConditionalOperators.when(ComparisonOperators.valueOf("author.middle").equalToValue(""))
+ .then("$$REMOVE").otherwiseValueOf("author.middle"))
+ .as("author.middle"));
+
+ Document document = aggregation.toDocument("books", Aggregation.DEFAULT_CONTEXT);
+
+ assertThat(document).isEqualTo(Document.parse(
+ "{\"aggregate\" : \"books\", \"pipeline\" : [{\"$project\" : {\"title\" : 1, \"author.middle\" : {\"$cond\" : {\"if\" : {\"$eq\" : [\"$author.middle\", \"\"]}, \"then\" : \"$$REMOVE\",\"else\" : \"$author.middle\"} }}}]}"));
+ }
+
@Test // DATAMONGO-757
public void usesImplictAndExplicitFieldAliasAndIncludeExclude() {
@@ -1715,4 +1732,17 @@ public class ProjectionOperationUnitTests {
return (Document) fromProjectClause.get(field);
}
+ @Data
+ static class Book {
+ String title;
+ Author author;
+ }
+
+ @Data
+ static class Author {
+ String first;
+ String last;
+ String middle;
+ }
+
}
diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc
index 6ea8bc8ba..1508e6050 100644
--- a/src/main/asciidoc/reference/mongodb.adoc
+++ b/src/main/asciidoc/reference/mongodb.adoc
@@ -2565,6 +2565,26 @@ List