OPTIONS

$ (update)

Definition

$

The positional $ operator identifies an element in an array to update without explicitly specifying the position of the element in the array. To project, or return, an array element from a read operation, see the $ projection operator.

The positional $ operator has the form:

{ "<array>.$" : value }

When used with update operations, e.g. db.collection.update() and db.collection.findAndModify(),

  • the positional $ operator acts as a placeholder for the first element that matches the query document, and
  • the array field must appear as part of the query document.

For example:

db.collection.update(
   { <array>: value ... },
   { <update operator>: { "<array>.$" : value } }
)

Behavior

upsert

Do not use the positional operator $ with upsert operations because inserts will use the $ as a field name in the inserted document.

Nested Arrays

The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value

Unsets

When used with the $unset operator, the positional $ operator does not remove the matching element from the array but rather sets it to null.

Negations

If the query matches the array using a negation operator, such as $ne, $not, or $nin, then you cannot use the positional operator to update values from this array.

However, if the negated portion of the query is inside of an $elemMatch expression, then you can use the positional operator to update this field.

Examples

Update Values in an Array

Consider a collection students with the following documents:

{ "_id" : 1, "grades" : [ 80, 85, 90 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

To update 80 to 82 in the grades array in the first document, use the positional $ operator if you do not know the position of the element in the array:

db.students.update(
   { _id: 1, grades: 80 },
   { $set: { "grades.$" : 82 } }
)

Remember that the positional $ operator acts as a placeholder for the first match of the update query document.

Update Documents in an Array

The positional $ operator facilitates updates to arrays that contain embedded documents. Use the positional $ operator to access the fields in the embedded documents with the dot notation on the $ operator.

db.collection.update(
   { <query selector> },
   { <update operator>: { "array.$.field" : value } }
)

Consider the following document in the students collection whose grades element value is an array of embedded documents:

{
  _id: 4,
  grades: [
     { grade: 80, mean: 75, std: 8 },
     { grade: 85, mean: 90, std: 5 },
     { grade: 90, mean: 85, std: 3 }
  ]
}

Use the positional $ operator to update the value of the std field in the embedded document with the grade of 85:

db.students.update(
   { _id: 4, "grades.grade": 85 },
   { $set: { "grades.$.std" : 6 } }
)

Update Embedded Documents Using Multiple Field Matches

The $ operator can update the first array element that matches multiple query criteria specified with the $elemMatch() operator.

Consider the following document in the students collection whose grades field value is an array of embedded documents:

{
  _id: 4,
  grades: [
     { grade: 80, mean: 75, std: 8 },
     { grade: 85, mean: 90, std: 5 },
     { grade: 90, mean: 85, std: 3 }
  ]
}

In the example below, the $ operator updates the value of the std field in the first embedded document that has grade field with a value less than or equal to 90 and a mean field with a value greater than 80:

db.students.update(
   {
     _id: 4,
     grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
   },
   { $set: { "grades.$.std" : 6 } }
)

This operation updates the first embedded document that matches the criteria, namely the second embedded document in the array:

{
  _id: 4,
  grades: [
    { grade: 80, mean: 75, std: 8 },
    { grade: 85, mean: 90, std: 6 },
    { grade: 90, mean: 85, std: 3 }
  ]
}