$ (update)
On this page
Definition
$
The positional
$
operator identifies an element in an array to update without explicitly specifying the position of the element in the array.NoteDisambiguation- 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 positional
operator
$[]
instead. - To update all elements that match an array filter condition or
conditions, 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 for the first element that matches thequery document
, and - the
array
field must appear as part of thequery document
.
For example:
db.collection.update( { <array>: value ... }, { <update operator>: { "<array>.$" : value } } ) - To project, or return, an array element from a read operation,
see the
Behavior
In MongoDB 4.4 and earlier, update operators process document fields in lexicographic order. See Update Operators Behavior for details.
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.
Multiple Array Matches
The positional $
update operator behaves ambiguously when filtering
on multiple array fields.
When the server executes an update method, it first runs a query to determine
which documents you want to update. If the update filters documents on multiple
array fields, the subsequent call to the positional $
update operator
doesn't always update the required position in the array.
For more information, see the example.
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 in
the grades
array, use the positional $
operator if you do
not know the position of the element in the array:
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 the
first match of the update query document.
After the operation, the students
collection contains the following
documents:
{ "_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 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: 85, mean: 85, std: 8 } ] }
Use the positional $
operator to update the std
field of
the first array element that matches the grade
equal to 85
condition:
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 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: 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 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.updateOne( { _id: 5, 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: 5, grades: [ { grade: 80, mean: 75, std: 8 }, { grade: 85, mean: 90, std: 6 }, { grade: 90, mean: 85, std: 3 } ] }
Update with Multiple Array Matches
The positional $
update operator behaves ambiguously when the
query has multiple array fields to filter documents in the collection.
Consider a document in the students_deans_list
collection, which holds
arrays of student information:
db.students_deans_list.insertMany( [ { _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2020 ] } ] )
In the following example, the user attempts to modify the deans_list
field,
filtering documents using the activity_ids
, deans_list
, and grades
fields, and updating the 2021 value in the deans_list
field to 2022:
db.students_deans_list.updateOne( { activity_ids: 1, grades: 95, deans_list: 2021 }, { $set: { "deans_list.$": 2022 } } )
When the server executes the updateOne
method above, it filters
the available documents using values in the supplied array fields.
Although the deans_list
field is used in the filter, it is not the field
used by the positional $
update operator to determine which position
in the array to update:
db.students_deans_list.find( { _id: 8 } )
Example output:
{ _id: 8, activity_ids: [ 1, 2 ], grades: [ 90, 95 ], deans_list: [ 2021, 2022 ] }
The updateOne
method matched the deans_list
field on 2021, but the
positional $
update operator instead changed the 2020 value to 2022.
To avoid unexpected results when matching on multiple arrays, instead
use the filtered positional operator $[<identifier>]
.