Definition:
The $set
operator in general is used to set the value of any field in a document to a new value.
When used to update an array field, $set
can be used to update the entire array, or to update a specific element in the array.
Syntax:
{ $set: { <field1>: <value1>, ... } }
//or
{ $set: { <field1.index>: <value1>, ... } }
Examples:
Consider the following document in a collection named products
:
{
"_id": 100,
"quantity": 250,
"instock": true,
"reorder": false,
"details": { "model": "14QQ", "make": "Clothes Corp" },
"tags": [ "apparel", "clothing" ],
"ratings": [ { "by": "Customer007", "rating": 4 } ]
}
(1) To update the enrite tags
field of the document :
db.products.updateOne(
{ _id: 100 },
{
$set:
{
tags: ["accessories", "fashion", "clothing"]
}
}
)
The previous update operation replaces the entire tags
array with a new array containing the values "accessories"
, "fashion"
, and "clothing"
.
After running this update operation, the tags
array in the document will be updated to:
"tags": [ "accessories", "fashion", "clothing" ]
(2) To update one specific item in the tags
field array :
db.products.updateOne(
{ _id: 100 },
{
$set:
{
"tags.1": "style"
}
}
)
The previous query uses dot notation
to access the second element in the tags array (index position 1) and sets its value to "style"
.
After running this update operation, the tags array in the document will be updated to:
"tags": [ "accessories", "style", "clothing" ]
Note that using $set
to update an entire array will replace the existing array with the new one, while using $set
with dot notation
to access a specific element in the array will modify only that element.
Definition:
The $
positional operator allows you to update specific elements of an array within a document without knowing it's exact location in the array.
When used in an update operation, it identifies the index of the matching element in the array and updates only that element.
Syntax:
{ "<array>.$" : value }
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.updateOne(
{ <array>: value ... },
{ <update operator $set|$inc>: { "<array>.$" : value } }
)
Examples:
(1) Consider the following documents in a collection named students
:
[
{ "_id" : 1, "grades" : [ 90, 80, 80 ] },
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 80, 100, 90 ] }
]
To update the first occurrence of the value 80
in the grades array with the value 82
:
db.students.updateOne(
{ _id: 1, grades: 80 },
{ $set: { "grades.$" : 82 } }
)
The resulting documents will look like this:
[
{ "_id" : 1, "grades" : [ 90, 82, 80 ] }, //changed
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 80, 100, 90 ] }
]
If you use updateMany()
instead of updateOne()
, it will update all documents that match the filter condition, the $
operator will update the first matching element in each matched document's array.
The query:
db.students.updateMany(
{ grades: 80 },
{ $set: { "grades.$" : 82 } }
)
The resulting documents will look like this:
[
{ "_id" : 1, "grades" : [ 85, 82, 80 ] }, //changed
{ "_id" : 2, "grades" : [ 88, 90, 92 ] },
{ "_id" : 3, "grades" : [ 82, 100, 90 ] } //changed
]
(2) Consider the following document in a collection named products
:
{
"_id": 100,
"quantity": 250,
"instock": true,
"details": { "model": "14QQ", "make": "Clothes Corp" },
"ratings":
[
{ "customer": "007", "rating": 4 },
{ "customer": "003", "rating": 2 },
{ "customer": "001", "rating": 3 }
]
}
The field ratings
is an array of objetcs contaning rating for each customer who bought the product.
To update the rating value of a specific customer :
db.products.updateOne(
{ _id: 100, "ratings.customer": "003" },
{ $set: { "ratings.$.rating" : 5 } }
)
The resulting ratings
array field will look like this:
"ratings": [
{ "customer": "007", "rating": 4 },
{ "customer": "003", "rating": 5 }, //changed
{ "customer": "001", "rating": 3 }
]
Note that the operator can only be used in the update object of an update operation, and not in the query object. In the query object, dot notation is used to access nested fields in the document.
Also remember that the array field need to be updated must appear as part of the query object.
Definition:
The $[]
operator is called the all positional operator
and is used to update all elements of an array within a document.
Syntax:
{ "<array>.$[]" : value }
unlike the $
positional operator, it can be used without putting the array in the query part, in other words, we can update the whole array.
Examples:
(1) Consider the following document in a collection named students
:
{
"_id" : 3,
"name": "Fady",
"grades" : [ 88, 90, 88, 85 ]
}
If you want to update the grades for a particular student with a certain name, you can use the $[]
operator in the update operation like this:
db.students.update(
{ name: "Fady" },
{ $set: { "grades.$[]": 90 } }
);
After running this update operation, the updated document will look like:
{
"_id" : 3,
"name": "Fady",
"grades" : [ 90, 90, 90, 90 ]
}
(2) Suppose you have the following documents in the students
collection:
[
{
"_id": 1,
"name": "Omnia",
"exams": [
{ "subject": "math", "score": 80 },
{ "subject": "english", "score": 90 },
{ "subject": "history", "score": 85 }
]
},
{
"_id": 2,
"name": "Ahmed",
"exams": [
{ "subject": "math", "score": 75 },
{ "subject": "english", "score": 80 },
{ "subject": "history", "score": 90 }
]
}
]
If you want to update the score
property for all objects in the exams
array where the subject property is "math"
, you can use the following query:
db.students.updateMany(
{ "exams.subject": "math" },
{ $set: { "exams.$[].score": 90 } }
)
After running this update operation, the updated documents will look like:
[
{
"_id": 1,
"name": "Omnia",
"exams": [
{ "subject": "math", "score": 90 },
{ "subject": "english", "score": 90 },
{ "subject": "history", "score": 85 }
]
},
{
"_id": 2,
"name": "Ahmed",
"exams": [
{ "subject": "math", "score": 90 },
{ "subject": "english", "score": 80 },
{ "subject": "history", "score": 90 }
]
}
]
Definition:
The arrayFilters
option is used to filter elements of an array field that match specific conditions.
This option allows you to specify a set of conditions to filter the elements of an array, and then update only the matching elements.
Syntax:
{ <update operator $set|$inc>: { "<array>.$[<identifier>]" : value } },
{ arrayFilters: [ { <identifier>: <condition> } ] }
the identifier
keyword is used to specify a placeholder for the matching element within the array that should be updated, and the arrayFilters
option is used to match the elements in the array that should be updated based on the identifier
value and a corresponding condition.
The identifier
keyword can be any word that is a valid JavaScript identifier. In other words, the identifier
can consist of letters, digits and underscores. However, the identifier cannot start with a digit.
It is recommended to use descriptive and meaningful identifier
to make the code more readable and understandable.
Examples:
(1) suppose you have a collection called users
with the following document:
{
"_id": 1,
"name": "Omnia",
"favorites": [ "pizza", "hiking", "coding" ]
}
If you want to update the "hiking"
value to "swimming"
in the favorites
array, you can use the arrayFilters
option as follows:
db.users.updateOne(
{ _id: 1 },
{ $set: { "favorites.$[element]": "swimming" } },
{ arrayFilters: [ { "element": "hiking" } ] }
)
After running the previous update operation, the favorites array in the document will look like:
[ "pizza", "swimming", "coding" ]
(2) Suppose we have a collection called students
with the following documents:
[
{ "_id" : 1, "grades" : [ 1, 5, 17 ] }
{ "_id" : 2, "grades" : [ 8, 17, 18 ] }
{ "_id" : 3, "grades" : [ 15, 11, 8 ] }
]
To updates all documents in the students collection by setting any value in the grades
array that is greater than or equal to 10
to 10
:
db.students.updateMany(
{},
{ $set: { "grades.$[grade]" : 10 } },
{ arrayFilters: [ { "grade": { $gte: 10 } } ] }
)
After running this update operation, the documents in the collection will look like:
[
{ "_id" : 1, "grades" : [ 1, 5, 10 ] }
{ "_id" : 2, "grades" : [ 8, 10, 10 ] }
{ "_id" : 3, "grades" : [ 10, 10, 8 ] }
]
(3) Suppose you have a document in a collection called employees
that has an array field called skills
:
{
"_id": 1,
"name": "Mohamed",
"skills": [
{ "name": "programming", "level": "expert" },
{ "name": "design", "level": "intermediate" },
{ "name": "marketing", "level": "beginner" }
]
}
If you want to update the level
of the skill with name equal to "programming"
from "expert"
value to "advanced"
value in the skills
array, you can use the arrayFilters
option as follows:
db.employees.updateOne(
{ _id: 1 },
{ $set: { "skills.$[skill].level": "advanced" } },
{ arrayFilters: [ { "skill.name": "programming" } ] }
)
After running this update operation, the skills
array in the document will look like:
[
{ "name": "programming", "level": "advanced" },
{ "name": "design", "level": "intermediate" },
{ "name": "marketing", "level": "beginner" }
]
✔️ How To Query Array Fields in MongoDB Documents
✔️ How To Add and Remove Array Elements in MongoDB Documents
🕴️ Linkedin: Dragon Slayer 🐲
📝 Articles: All Articles written by D.S