How do I use Spring Mongo to group two fields and get an array from one field based on the other?
Let me give you an example here:
Two entries in the collection By:
{
"name" : "Joe"
"Book" : "A"
},
{
"name" : "Joe"
"Book" : "B"
}
Now if I use the aggregation function in Mongo via spring mongo, mostly just to grab books named Joe, it can be coded like this:
Aggregation agg = newAggregation(Map.class, group("name", "Book"));
AggregationResults<Map> results = mongoTemplate.aggregate(agg, "Author",
Map.class);
Obviously I could get two Cards this way, one has an entry {"name":"Joe", "Book": A}
, the other has{"name" : "Joe", "Book" : "B"}
But what if I want to get ONLY one result back, with one entry:
{"name" : Joe, "Books" : ["A", "B"]}?
I'm not sure if only one request is available. This can certainly be achieved in a few steps that I would not like to take.
source to share
You need to use the operator in . This will return an array of all unique values that results from applying the expression to every document in a group of documents that use the same group by key . So in mongo shell you have $addToSet
$group
["A", "B"]
$group
"name"
db.author.aggregate([
{
"$group": {
"_id": "$name",
"Books": {
"$addToSet": "$Book"
}
}
}
]);
which returns the desired result
{
"result" : [
{
"_id" : "Joe",
"Books" : [ "B", "A" ]
}
],
"ok" : 1
}
Equivalent Spring aggregation:
Aggregation agg = newAggregation(Map.class, group("name").addToSet("Book").as("Books"));
AggregationResults<Map> results = mongoTemplate.aggregate(agg, "Author", Map.class);
source to share