Reputation: 1529
Do anyone know how to convert the below aggregation function into a java code using Spring-data?
db.myCollection.aggregate([
{$match:{"status" : {$in:["WORKING","UNASSIGNED"]}}},
{$group:{
_id:{
"status":"$status",
"queue":"$queueName"
},
"count":{$sum:1},
"oldest":{$min:"$queueTime"},
"slow":{$sum:{$cond:[
{$lte: ["$queueServiceTs", new Date()]},
1,
0]}
}
}
}
]);
Upvotes: 4
Views: 1707
Reputation: 50416
Spring mongo does not currently support either:
A composite aggregation _id
with custom key names, though of course you could just accept the defualt field name translation
Usage of the $cond
operation or any expression within a $sum
, as it just supports a mapped field only.
So the second there is the thing that breaks usage of the aggregation helper functions in this case. You could work around that by doing a $project
first, but that requires an additional stage of execution that will affect the performance.
But what you can do is create your own abstract class that works within the standard builder functions but allows you to build the pipeline stage with standard objects:
public class CustomGroupOperation implements AggregationOperation {
private DBObject operation;
public CustomGroupOperation (DBObject operation) {
this.operation = operation;
}
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
And then you can use it with the standard builder as follows:
Aggregation aggregation = newAggregation(
new CustomGroupOperation(
new BasicDBObject("$group",
new BasicDBObject("_id",
new BasicDBObject("status","$status")
.append("queue","$queueName")
)
.append("count",new BasicDBObject("$sum",1))
.append("oldest", new BasicDBObject("$min","$queueTime"))
.append("slow",
new BasicDBObject("$sum",
new BasicDBObject("$cond",Arrays.asList(
new BasicDBObject("$lte",Arrays.asList(
"$queueServiceTs",
new Date()
)),
1,
0
))
)
)
)
)
);
And that builds a pipeline with the $group
stage exactly as you have it defined.
Upvotes: 6