I am looking to aggregate the following data
{
"user": "user1",
"error": true
}
{
"user": "user2",
"error": false
}
{
"user": "user1",
"error": false
}
Into
{
"_id": "user1",
"errorCount": 1,
"totalCount": 2
},
{
"_id": "user2",
"errorCount": 0,
"totalCount": 1
}
With $cond operator, this can be achieved using:
$group: {
_id: "$user",
errorCount : { "$sum" : {"$cond" : ["$error", 1, 0]}},
totalCount : { "$sum" : 1 }
}
However, since I am using Spring-data-mongodb which does not yet support $cond (as of 1.3.4-RELEASE), I couldn't do this.
Is there a way to do the same aggregation without $cond?
Thanks to Neil Lunn's suggestion, I have managed to get $cond to using aggregation support from spring-data. To do this, you have to implement the AggregationOperation interface to take in a DBObject.
public class DBObjectAggregationOperation implements AggregationOperation {
private DBObject operation;
public DBObjectAggregationOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
Then you will be able to use it in TypeAggregation normally:
DBObject operation = (DBObject)JSON.parse ("your pipleline here...");
TypedAggregation<UserStats> aggregation = newAggregation(User.class,
new DBObjectAggregationOperation(operation)
);
AggregationResults<UserStats> result = mongoTemplate.aggregate(aggregation, UserStats.class);
This approach will allow you to use any aggregation operator not yet defined in the framework. However, it also bypassed the validation put in place by spring-data and should be used with caution.
Please vote if you would like to have $cond operator supported properly through the framework: https://jira.springsource.org/browse/DATAMONGO-861
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With