skip to Main Content
Below is sample doc of collection.
{
name:"sam",
age:20,
hobbies: [ {id:1, value: "football"}, {id:2 value:"chess"} ]
},
{
  "name": "Bob",
  "age": 30,
  "hobbies": [
    { "id": 1, "value": "painting" },
    { "id": 2, "value": "gardening" }
  ]
},
{
  "name": "Charlie",
  "age": 22,
  "hobbies": [
    { "id": 1, "value": "cycling" },
    { "id": 2, "value": "playing the guitar" },
    { "id": 3, "value": "photography" }
  ]
}

I have tried using the below query, it only sorts the array of hobbies not the documents of the collection.

{$sort : {"hobbies.value": -1}}

I want to sort documents of the collection based on hobbies.value and also sort objects inside the array.
The expected result will be something like below for asc. .

{
name:"sam",
age:20,
hobbies: [ {id:2 value:"chess"}, {id:1, value: "football"} ]
},
{
  "name": "Charlie",
  "age": 22,
  "hobbies": [
    { "id": 1, "value": "cycling" },
    { "id": 2, "value": "playing the guitar" },
    { "id": 3, "value": "photography" }
  ]
},
{
  "name": "Bob",
  "age": 30,
  "hobbies": [
    { "id": 1, "value": "painting" },
    { "id": 2, "value": "gardening" }
  ]
}

2

Answers


    1. Your current query is sorting the hobbies.value array by descending not ascending. You should use { "hobbies.value": 1 }

    2. To sort the objects in an array, you need the $sortArray operator.

    db.collection.aggregate([
      {
        $sort: {
          "hobbies.value": 1
        }
      },
      {
        $set: {
          hobbies: {
            $sortArray: {
              input: "$hobbies",
              sortBy: {
                value: 1
              }
            }
          }
        }
      }
    ])
    

    Demo @ Mongo Playground

    Login or Signup to reply.
  1. Sorting documents by an array field is not intuitive. From the Comparison Sort Order docs:

    In array comparisons:

    A less-than comparison, or an ascending sort, compares the smallest elements of the array according to the BSON type sort order.

    A greater-than comparison, or a descending sort, compares the largest elements of the array according to the reverse BSON type sort order.

    When comparing a field whose value is a one element array (example, [ 1 ]) with non-array fields (example, 2), the comparison is for 1 and 2.

    A comparison of an empty array (example, [ ]) considers the empty array as less than a null value or a missing field value.

    {$sort:{"hobbies.value":-1}} would sort the sample documents you provided in the order Charlie, Bob, Sam, because the values considered for the sort would be "playing the guitar", "painting", and "football".

    to sort the values within the array, use the $sortArray operator in a $project or $addFields stage.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search