I know this question has been asked a million times before here, but I cannot find anything matching my use case. Probably due to lack of knowledge of the Spring Mongo aggregation framework. I hope someone can shed some light on the subject for me.
Mongo shell aggregation
db.mongoAuditEvent.aggregate([
{$group: {_id : "$corrId", currentEvent: {"$last": "$event.status"}, events: { $push: "$$ROOT"} }},
{$sort: {"timestamp": 1} },
{$skip: 0 },
{$limit: 10}
], {allowDiskUse: true}).pretty()
Produces
{
"_id" : "00aa9c60-2950-439b-976e-0980da829981",
"currentEvent" : "UPSTREAM_QUEUE",
"events" : [
{
"_id" : "e746cd3f-dfe3-47b3-a1d0-3342adaf61c3",
"_class" : "no.fint.audit.plugin.mongo.MongoAuditEvent",
"corrId" : "00aa9c60-2950-439b-976e-0980da829981",
"source" : "employee",
"timestamp" : NumberLong("1484478431288"),
"event" : {
"corrId" : "00aa9c60-2950-439b-976e-0980da829981",
"action" : "GET_ALL_EMPLOYEES",
"status" : "DOWNSTREAM_QUEUE",
"time" : NumberLong("1484478431287"),
"source" : "employee",
"client" : "CACHE_SERVICE"
},
"clearData" : true
}
]
}
I managed to translate this to the following in Spring:
public List<DBObject> getAllAuditEvents(Integer page, Integer pageSize) {
List<DBObject> agg = new ArrayList();
agg.add(BasicDBObject.parse("{$group: {_id: \"$corrId\", currentEvent: {\"$last\": \"$event.status\"}, events: { $push: \"$$ROOT\"} }}"));
agg.add(BasicDBObject.parse("{$sort: {\"timestamp\": -1} }"));
agg.add(BasicDBObject.parse("{$limit: " + pageSize + "}"));
agg.add(BasicDBObject.parse("{$skip: " + (page * pageSize) + " }"));
return (List<DBObject>) mongoTemplate.getCollection("mongoAuditEvent")
.aggregate(agg).results();
}
But this fails because I have not specified the allowDiskUse:true option anywhere, and I cannot seem to find the right place to specify it.
Then I saw that there's a more preferred way of specifying aggregations:
public List<MongoAuditEventGroup> getAllAuditEvents(Integer page, Integer pageSize) {
return mongoTemplate.aggregate(
Aggregation.newAggregation(
Aggregation.group("corrId"),
Aggregation.sort(Sort.Direction.DESC, "corrId"),
Aggregation.limit(pageSize),
Aggregation.skip((long)page * pageSize)
).withOptions(newAggregationOptions().allowDiskUse(true).build()),
MongoAuditEvent.class,
MongoAuditEventGroup.class).getMappedResults();
}
But I cannot seem to wrap my head around how to add the currentEvent to the group.
I would be very grateful for any help or pointers anybody could give me here.