I am trying to implement a grouping with a TopN aggregation operator using spring-data-mongo and I am lost on how to do it.
I know what I want from the POV of MongoDB. It’s something like this:
[ {
$match: {
field000: { $regex: ".*MATCHTHIS.*" },
created: { $lte: new Date("2030-05-25T00:00:00.000+00:00" ) }
},
},
{
$group: {
_id: "$field001",
field001s: {
$topN: {
output: ["$field002", "$created"],
sortBy: { created: -1, },
n: 1,
}
}
}
}]
Meaning … for the set of documents already filtered by the $match clause; group by field001, order each bucket by created desc, and pick the top (1). So the most recently created documents for each group category.
I find problems to translate this into spring-data-mongo
2
Answers
After a lot of research, I realized this question is probably easily solvable on spring-data-mongodb most recent versions since "topN" aggregation operator is implemented. However in my case upgrading the stack to support that version is not an option.
On the other hand, if you are using repositories then the @Charchit Kapoor solution is probably the best one.
If you want to stick with mongo template it can be done this way:
You can split this into different methods for better readability.
Using
MongoRepository
, you can specify the pipeline using,@Aggregate
annotation. Something like this:Note that I have parameterized the search regex and date value. Please update it accordingly, along with the return type of the function. Using
MongoTemplate
, you can try something along these lines.Note that, I have added two new stages for
Projection
andSorting
, as$topN
is not yet supported by Spring Data MongoDB, so I am projecting the necessary fields, then sorting bycreated
, and then grouping the document and picking the first one in each group.Note: The answer is not tested by me, so you will have to try it out and adjust it.