I am looking for an up-to-date example on how to do "sum" and "date" aggregations with the MongoDB Java Driver. I am using mongodb-driver-sync version 4.11.1.
Having the following data model:
{
"_id": {
"$oid": "654e3f36582773107c4570f1"
},
"booked": {
"$date": "2011-01-05T01:00:00.000Z"
},
"amount": {
"$numberDecimal": "45.08"
}
}
First thing i'd like to do is sum the amount of all data entries. However, the examples I have found, only use "count" which doesn't help much. One example of this is on the official documentation.
Arrays.asList(
Aggregates.match(Filters.eq("categories", "Bakery")),
Aggregates.group("$stars", Accumulators.sum("count", 1))
)
Second thing i'd like to do is to group by month or year sometimes both. Based one the documentation, I would assume this should be done with Accumulators, but there are no date based Accumulators, only sum, avg, etc. So something like this won't work:
List<Bson> pipeline = Arrays.asList(group("_id", Accumulators.month ... ));
Answer my own question in hope that it will help:
For getting the sum it was pretty simple by just using an Accumulator.
Bson groupStage = group("_id", Accumulators.sum("totalAmount", "$amount"));
AggregateIterable aggregation = collection("bookings").aggregate(of(matchStage, groupStage));
The trick here is to watch out if your are aggregation on POJOa or on the collection. If you have a field (in this case totalAmount) in your POJO than this works fine, otherwise it will return null in your POJO. As for the example, I decided to aggregate on the collection.
For group on date, it seems there are no direct classes in the Java Mongo Driver, so I decided to use the direct JSON equivalent and ended up with:
Bson groupStage = group(Document.parse("{'year': { $year: '$booked' }}"));
AggregateIterable aggregation = collection("bookings").aggregate(Arrays.asList(groupStage));