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.

+3


source to share


1 answer


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);

      

+2


source







All Articles