DATAMONGO-861 - Add support for $cond and $ifNull operators in aggregation operations.

We now support $cond and $ifNull operators for projection and grouping operations. ConditionalOperator and IfNullOperators are AggregationExpressions that can be applied to transform or generate values during aggregation.

TypedAggregation<InventoryItem> agg = newAggregation(InventoryItem.class,
  project().and("discount")
    .transform(ConditionalOperator.newBuilder().when(Criteria.where("qty").gte(250))
      .then(30)
      .otherwise(20))
    .and(ifNull("description", "Unspecified")).as("description")
);

corresponds to

{ "$project": { "discount": { "$cond": { "if": { "$gte": [ "$qty", 250 ] },
        "then": 30, "else": 20 } },
    "description": { "$ifNull": [ "$description", "Unspecified"] }
  }
}

Original Pull Request: #385
This commit is contained in:
Mark Paluch
2016-07-08 16:44:13 +02:00
committed by Christoph Strobl
parent 116dda63c2
commit ace01e4e6d
11 changed files with 1527 additions and 7 deletions

View File

@@ -4,6 +4,7 @@
[[new-features.1-10-0]]
== What's new in Spring Data MongoDB 1.10
* Support for `$min`, `$max` and `$slice` operators via `Update`.
* Support for `$cond` and `$ifNull` operators via `Aggregation`.
[[new-features.1-9-0]]
== What's new in Spring Data MongoDB 1.9

View File

@@ -1688,6 +1688,9 @@ At the time of this writing we provide support for the following Aggregation Ope
| Array Aggregation Operators
| size, slice
| Conditional Aggregation Operators
| cond, ifNull
|===
Note that the aggregation operations not listed here are currently not supported by Spring Data MongoDB. Comparison aggregation operators are expressed as `Criteria` expressions.
@@ -1985,6 +1988,50 @@ List<DBObject> resultList = result.getMappedResults();
Note that we can also refer to other fields of the document within the SpEL expression.
[[mongo.aggregation.examples.example6]]
.Aggregation Framework Example 6
This example uses conditional projection. It's derived from the https://docs.mongodb.com/manual/reference/operator/aggregation/cond/[$cond reference documentation].
[source,java]
----
public class InventoryItem {
@Id int id;
String item;
String description;
int qty;
}
public class InventoryItemProjection {
@Id int id;
String item;
String description;
int qty;
int discount
}
----
[source,java]
----
import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
TypedAggregation<InventoryItem> agg = newAggregation(InventoryItem.class,
project("item").and("discount")
.transform(ConditionalOperator.newBuilder().when(Criteria.where("qty").gte(250))
.then(30)
.otherwise(20))
.and(ifNull("description", "Unspecified")).as("description")
);
AggregationResults<InventoryItemProjection> result = mongoTemplate.aggregate(agg, "inventory", InventoryItemProjection.class);
List<InventoryItemProjection> stateStatsList = result.getMappedResults();
----
* This one-step aggregation uses a projection operation with the `inventory` collection. We project the `discount` field using a conditional transformation for all inventory items that have a `qty` greater or equal to `250`. An second conditional projection is performed for the `description` field. We apply the description `Unspecified` to all items that either do not have a `description` field of items that have a `null` description.
[[mongo.custom-converters]]
== Overriding default mapping with custom converters