Limit Number of Elements in an Array after an Update

On this page

New in version 2.4.

Synopsis

Consider an application where users may submit many scores (e.g. for a test), but the application only needs to track the top three test scores.

This pattern uses the $push operator with the $each, $sort, and $slice modifiers to sort and maintain an array of fixed size.

Pattern

Consider the following document in the collection students:

{
  _id: 1,
  scores: [
    { attempt: 1, score: 10 },
    { attempt: 2 , score:8 }
  ]
}

The following update uses the $push operator with:

  • the $each modifier to append to the array 2 new elements,
  • the $sort modifier to order the elements by ascending (1) score, and
  • the $slice modifier to keep the last 3 elements of the ordered array.
db.students.update(
   { _id: 1 },
   {
     $push: {
        scores: {
           $each: [ { attempt: 3, score: 7 }, { attempt: 4, score: 4 } ],
           $sort: { score: 1 },
           $slice: -3
        }
     }
   }
)

Note

When using the $sort modifier on the array element, access the field in the embedded document element directly instead of using the dot notation on the array field.

After the operation, the document contains only the top 3 scores in the scores array:

{
   "_id" : 1,
   "scores" : [
     { "attempt" : 3, "score" : 7 },
     { "attempt" : 2, "score" : 8 },
     { "attempt" : 1, "score" : 10 }
   ]
}

See also