OPTIONS

$sort

$sort

New in version 2.4.

The $sort modifier orders the elements of an array during a $push operation.

To use the $sort modifier, it must appear with the $each modifier.

Tip

You can pass an empty array [] to the $each modifier such that only the $sort modifier has an effect.

    Changed in version 2.6:
  • The $sort modifier can sort array elements that are not documents. In previous versions, the $sort modifier required the array elements be documents.

  • If the array elements are documents, the modifier can sort by either the whole document or by a specific field in the documents. In previous versions, the $sort modifier can only sort by a specific field in the documents.

  • The $sort no longer requires the $slice modifier.

  • Trying to use the $sort modifier without the $each modifier results in an error.

db.collection.update( <query>,
                      { $push: {
                                 <arrayField>: {
                                                  $each: [ <value1>,
                                                           <value2>,
                                                           ...
                                                         ],
                                                  $sort: <sort specification>,
                                               }
                               }
                      }
                    )

For <sort specification>:

  • To sort array elements that are not documents, or if the array elements are documents, to sort by the whole documents, specify 1 for ascending or -1 for descending.
  • If the array elements are documents, to sort by a field in the documents, specify a sort document with the field and the direction, i.e. { field: 1 } or { field: -1 }. Do not reference the containing array field in the sort specification (e.g. { "arrayField.field": 1 } is incorrect).

Examples

Sort Array of Documents by a Field in the Documents

A collection students contains the following document:

{ "_id": 1,
  "quizzes": [
               { "id" : 1, "score" : 6 },
               { "id" : 2, "score" : 9 }
             ]
}

The following update appends additional documents to the quizzes array and then sorts all the elements of the array by the ascending score field:

db.students.update( { _id: 1 },
                    { $push: { quizzes: { $each: [ { id: 3, score: 8 },
                                                   { id: 4, score: 7 },
                                                   { id: 5, score: 6 } ],
                                          $sort: { score: 1 },
                                        }
                             }
                    }
                  )

Important

The sort document refers directly to the field in the documents and does not reference the containing array field quizzes; i.e. { score: 1 } and not { "quizzes.score": 1}

After the update, the array elements are in order of ascending score field.:

{
  "_id" : 1,
  "quizzes" : [
                { "id" : 1, "score" : 6 },
                { "id" : 5, "score" : 6 },
                { "id" : 4, "score" : 7 },
                { "id" : 3, "score" : 8 },
                { "id" : 2, "score" : 9 }
              ]
}

Sort Array Elements That Are Not Documents

A collection students contains the following document:

{ "_id" : 2, "tests" : [  89,  70,  89,  50 ] }

The following operation adds two more elements to the scores array and sorts the elements:

db.students.update(
                    { _id: 2 },
                    { $push: { tests: { $each: [ 40, 60 ], $sort: 1 } } }
                  )

The updated document has the elements of the scores array in ascending order:

{ "_id" : 2, "tests" : [  40,  50,  60,  70,  89,  89 ] }

Update Array Using Sort Only

A collection students contains the following document:

{ "_id" : 3, "tests" : [  89,  70,  100,  20 ] }

To update the tests field to sort its elements in descending order, specify the { $sort: -1 } and specify an empty array [] for the $each modifier, as in the following:

db.students.update(
                    { _id: 3 },
                    { $push: { tests: { $each: [ ], $sort: -1 } } }
                  )

The result of the operation is to update the scores field to sort its elements in descending order:

{ "_id" : 3, "tests" : [ 100,  89,  70,  20 ] }

Use $sort with Other $push Modifiers

A collection students has the following document:

{
   "_id" : 5,
   "quizzes" : [
                  { wk: 1, "score" : 10 },
                  { wk: 2, "score" : 8 },
                  { wk: 3, "score" : 5 },
                  { wk: 4, "score" : 6 }
               ]
}

The following $push operation uses:

  • the $each modifier to add multiple documents to the quizzes array,
  • the $sort modifier to sort all the elements of the modified quizzes array by the score field in descending order, and
  • the $slice modifier to keep only the first three sorted elements of the quizzes array.
db.students.update( { _id: 5 },
                    { $push: { quizzes: { $each: [ { wk: 5, score: 8 },
                                                   { wk: 6, score: 7 },
                                                   { wk: 7, score: 6 } ],
                                          $sort: { score: -1 },
                                          $slice: 3
                                        }
                             }
                    }
                  )

The result of the operation is keep only the three highest scoring quizzes:

{ "_id" : 5,
  "quizzes" : [
                { "wk" : 1, "score" : 10 },
                { "wk" : 2, "score" : 8 },
                { "wk" : 5, "score" : 8 }
              ]
}

The order of the modifiers is immaterial to the order in which the modifiers are processed. See Modifiers for details.

←   $slice $position  →