Marjan
Marjan

Reputation: 1418

Sort by values of documents in nested arrays in Mongo

I have a collection called Objects. Each Object document has a nested array of documents called properties. Each property document has a name and a value.

For example, let's say I have these two objects, each having two properties (height and width). How would I sort the objects by height?

{
  "id": 1,
  "properties": [
    {
      "name": "height",
      "value": 170
    },
    {
      "name": "width",
      "value": 200
    },
  ]
},
{
  "id": 2,
  "properties": [
    {
      "name": "height",
      "value": 100
    },
    {
      "name": "width",
      "value": 300
    },
  ]
}

Upvotes: 5

Views: 6090

Answers (1)

Anand Jayabalan
Anand Jayabalan

Reputation: 12904

In most cases, MongoDB's aggregation framework is your friend whenever you are dealing with arrays. Take a look at the $unwind operator that can be use to break the array into individual documents. I've posted a sample query below to sort the documents by height. Note that you can use the $project operator in the aggregation pipeline to better format the results.

db.objects.aggregate([
    // De-normalize the 'properties' array
    {$unwind:"$properties"}, 
    // Filter for only height
    {$match:{"properties.name":"height"}},
    // Sort by 'height' in ascending order.  Use -1 for descending 
    {$sort:{"properties.value":1}}
])

EDIT: One way to keep the properties element intact is to make a copy of it just to be used for sorting. An example is below:

db.objects.aggregate([
    // Make a copy of the 'properties' element
    {$project:{properties:1, sortfield:"$properties"}}, 
    {$unwind:"$sortfield"}, 
    {$match:{"sortfield.name":"height"}}, 
    {$sort:{"sortfield.value":1}}, 
    // Get rid of 'sortfield' 
    {$project:{properties:1}}
])

Upvotes: 10

Related Questions