Malibur
Malibur

Reputation: 1773

Mongoose aggregation: Documents with a specific object property in array of objects

Let's say you have a collections with thousands of football players like these two

[
    {
           "_id" : ObjectId("5e19d76fa45abb5d4d50c1d3"),
           "name" : "Leonel Messi",
           "country" : "Argentina",
           "awards" : [
                   {
                           "award" : "Ballon d'Or",
                           "year" : 1972
                   },
                   {
                           "award" : "Golden Boot",
                           "year" : 1971
                   },
                   {
                           "award" : "FIFA World Player of the Year",
                           "year" : 1988
                   }
           ]
    },
    {
           "_id" : ObjectId("53w9d76fa45abb5d4d30c112"),
           "name" : "Lars Sørensen",
           "country" : "Denmark",
           "awards" : [
                   {
                           "award" : "Ballon d'Or",
                           "year" : 1971
                   },
           ]
    }
]

"awards" can contain any number of objects.

I would like to return all the players, with a boolean property on whether they have won the "Golden Boot" award or not. So something like this:

 [
    {
        "name" : "Leonel Messi",
        "won_golden_boot" : true,
    },
    {
        "name" : "Lars Sørensen",
        "won_golden_boot" : false,
    }
]

But I struggle to figure out how I use the aggregation stages to do this? Do I use $map? $in? and if so, how would they come ind her:

{ $sort: { name: 1 } },

// What goes here??

{ 
    $project: {
        name: "$name",
        won_golden_boot: "$won?",
    } 
},

Upvotes: 0

Views: 787

Answers (1)

J.F.
J.F.

Reputation: 15177

You can use this aggregation query:

This query use $project as you have done but for won_golden_boot do a condition $cond checking if exists an award called Golden Boot using $in operator.

db.collection.aggregate([
  {
    "$project": {
      "name": "$name",
      "won_golden_boot": {
        "$cond": {
          "if": {
            "$in": [
              "Golden Boot",
              "$awards.award"
            ]
          },
          "then": true,
          "else": false
        }
      }
    }
  }
])

Example here

Edit:

I know this is question is specifically to use aggregation, but in case is useful for somebody is possible to do this using find like this example

Upvotes: 1

Related Questions