$ (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:
- { "<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 thequery document
, and - the
array
field must appear as part of thequerydocument
.For example:
- db.collection.update(
- { <array>: value ... },
- { <update operator>: { "<array>.$" : value } }
- )
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:
- db.students.insert([
- { "_id" : 1, "grades" : [ 85, 80, 80 ] },
- { "_id" : 2, "grades" : [ 88, 90, 92 ] },
- { "_id" : 3, "grades" : [ 85, 100, 90 ] }
- ])
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.
- db.students.updateOne(
- { _id: 1, grades: 80 },
- { $set: { "grades.$" : 82 } }
- )
The positional $
operator acts as a placeholder for thefirst match of the update query document.
After the operation, the students
collection contains the followingdocuments:
- { "_id" : 1, "grades" : [ 85, 82, 80 ] }
- { "_id" : 2, "grades" : [ 88, 90, 92 ] }
- { "_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.
- db.collection.update(
- { <query selector> },
- { <update operator>: { "array.$.field" : value } }
- )
Consider the following document in the students
collection whosegrades
element value is an array of embedded documents:
- {
- _id: 4,
- grades: [
- { grade: 80, mean: 75, std: 8 },
- { grade: 85, mean: 90, std: 5 },
- { grade: 85, mean: 85, std: 8 }
- ]
- }
Use the positional $
operator to update the std
field ofthe first array element that matches the grade
equal to 85
condition:
Important
You must include the array field as part of the query
document.
- db.students.updateOne(
- { _id: 4, "grades.grade": 85 },
- { $set: { "grades.$.std" : 6 } }
- )
After the operation, the document has the following updated values:
- {
- "_id" : 4,
- "grades" : [
- { "grade" : 80, "mean" : 75, "std" : 8 },
- { "grade" : 85, "mean" : 90, "std" : 6 },
- { "grade" : 85, "mean" : 85, "std" : 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:
- {
- _id: 5,
- 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 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
:
- db.students.updateOne(
- {
- _id: 5,
- grades: { $elemMatch: { grade: { $lte: 90 }, mean: { $gt: 80 } } }
- },
- { $set: { "grades.$.std" : 6 } }
- )
This operation updates the first embedded document that matches thecriteria, namely the second embedded document in the array:
- {
- _id: 5,
- grades: [
- { grade: 80, mean: 75, std: 8 },
- { grade: 85, mean: 90, std: 6 },
- { grade: 90, mean: 85, std: 3 }
- ]
- }
See also
db.collection.update()
,db.collection.findAndModify()
, $elemMatch()