$ (update)

Definition

  • $
  • The positional $ operator identifies an element inan array to update without explicitly specifying the position of theelement in the array.

Disambiguation

  • To project, or return, an array element from a read operation,see the $ projection operator instead.
  • To update all elements in an array, see the all positionaloperator $[] instead.
  • To update all elements that match an array filter condition orconditions, see the filtered positional operator instead$[<identifier>].

The positional $ operator has the form:

  1. { "<array>.$" : value }

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

  • the positional $ operator acts as a placeholder forthe first element that matches the query document, and
  • the array field must appear as part of the querydocument.For example:
  1. db.collection.update(
  2. { <array>: value ... },
  3. { <update operator>: { "<array>.$" : value } }
  4. )

Behavior

upsert

Do not use the positional operator $ withupsert operations because inserts will use the $ asa field name in the inserted document.

Nested Arrays

The positional $ operator cannot be used for queries whichtraverse more than one array, such as queries that traverse arraysnested 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 elementfrom 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 thepositional 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 positionaloperator to update this field.

Examples

Update Values in an Array

Create a collection students with the following documents:

  1. db.students.insert([
  2. { "_id" : 1, "grades" : [ 85, 80, 80 ] },
  3. { "_id" : 2, "grades" : [ 88, 90, 92 ] },
  4. { "_id" : 3, "grades" : [ 85, 100, 90 ] }
  5. ])

To update the first element whose value is 80 to 82 in the inthe grades array, use the positional $ operator if you donot know the position of the element in the array:

Important

You must include the array field as part of the query document.

  1. db.students.updateOne(
  2. { _id: 1, grades: 80 },
  3. { $set: { "grades.$" : 82 } }
  4. )

The positional $ operator acts as a placeholder for thefirst match of the update query document.

After the operation, the students collection contains the followingdocuments:

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

Update Documents in an Array

The positional $ operator facilitates updates to arraysthat contain embedded documents. Use the positional $operator to access the fields in the embedded documents with thedot notation on the$ operator.

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

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

  1. {
  2. _id: 4,
  3. grades: [
  4. { grade: 80, mean: 75, std: 8 },
  5. { grade: 85, mean: 90, std: 5 },
  6. { grade: 85, mean: 85, std: 8 }
  7. ]
  8. }

Use the positional $ operator to update the std field ofthe first array element that matches the grade equal to 85condition:

Important

You must include the array field as part of the query document.

  1. db.students.updateOne(
  2. { _id: 4, "grades.grade": 85 },
  3. { $set: { "grades.$.std" : 6 } }
  4. )

After the operation, the document has the following updated values:

  1. {
  2. "_id" : 4,
  3. "grades" : [
  4. { "grade" : 80, "mean" : 75, "std" : 8 },
  5. { "grade" : 85, "mean" : 90, "std" : 6 },
  6. { "grade" : 85, "mean" : 85, "std" : 8 }
  7. ]
  8. }

Update Embedded Documents Using Multiple Field Matches

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

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

  1. {
  2. _id: 5,
  3. grades: [
  4. { grade: 80, mean: 75, std: 8 },
  5. { grade: 85, mean: 90, std: 5 },
  6. { grade: 90, mean: 85, std: 3 }
  7. ]
  8. }

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

  1. db.students.updateOne(
  2. {
  3. _id: 5,
  4. grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
  5. },
  6. { $set: { "grades.$.std" : 6 } }
  7. )

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

  1. {
  2. _id: 5,
  3. grades: [
  4. { grade: 80, mean: 75, std: 8 },
  5. { grade: 85, mean: 90, std: 6 },
  6. { grade: 90, mean: 85, std: 3 }
  7. ]
  8. }

See also

db.collection.update(),db.collection.findAndModify(), $elemMatch()