We use $[identifier] to update only certain items inside an array in a document. It helps change specific parts without touching everything.
Array update with $[identifier] filtered in MongoDB
db.collection.updateOne(
{ <filter> },
{ $set: { "arrayField.$[identifier].fieldToUpdate": newValue } },
{ arrayFilters: [ { "identifier.conditionField": conditionValue } ] }
)The $[identifier] is a placeholder for array elements that match the filter in arrayFilters.
You must provide arrayFilters to tell MongoDB which array items to update.
db.students.updateOne(
{ name: "Alice" },
{ $set: { "grades.$[elem].score": 95 } },
{ arrayFilters: [ { "elem.subject": "Math" } ] }
)db.orders.updateOne(
{ orderId: 123 },
{ $set: { "items.$[item].shipped": true } },
{ arrayFilters: [ { "item.status": "packed" } ] }
)db.library.updateOne(
{ name: "City Library" },
{ $set: { "books.$[book].available": false } },
{ arrayFilters: [ { "book.genre": "Horror" } ] }
)This example creates a user John with hobbies. It updates only hobbies of type 'sports' to have level 'expert'.
db.users.insertOne({
name: "John",
hobbies: [
{ type: "sports", name: "soccer", level: "beginner" },
{ type: "music", name: "guitar", level: "intermediate" },
{ type: "sports", name: "tennis", level: "advanced" }
]
});
// Before update
printjson(db.users.findOne({ name: "John" }));
// Update only sports hobbies to level "expert"
db.users.updateOne(
{ name: "John" },
{ $set: { "hobbies.$[hobby].level": "expert" } },
{ arrayFilters: [ { "hobby.type": "sports" } ] }
);
// After update
printjson(db.users.findOne({ name: "John" }));Time complexity depends on the number of array elements and the filter conditions.
Space complexity is minimal as only matching elements are updated.
Common mistake: forgetting to include arrayFilters causes no update or error.
Use $[identifier] when you want to update specific array elements. Use $ positional operator only if you update the first matching element.
$[identifier] lets you update specific items inside arrays.
You must use arrayFilters to tell MongoDB which items to update.
This helps avoid changing the whole array or wrong elements.
Practice
$[identifier] syntax do in a MongoDB update operation?Solution
Step 1: Understand
The$[identifier]usage$[identifier]syntax is used to target specific elements inside an array during an update.Step 2: Role of
ThearrayFiltersarrayFiltersoption specifies which array elements the$[identifier]refers to, so only those elements get updated.Final Answer:
It updates only the array elements that match the filter specified inarrayFilters. -> Option AQuick Check:
$[identifier]updates filtered array items [OK]
- Thinking $[identifier] updates the whole array
- Confusing $[identifier] with $push or $set without filters
- Ignoring the need for arrayFilters option
$[elem] with arrayFilters in MongoDB?Solution
Step 1: Identify correct update operator and syntax
The$setoperator is used to update existing fields. The positional filtered identifier must be inside square brackets like$[elem].Step 2: Confirm usage of
ThearrayFiltersarrayFiltersoption must be provided with a filter object matching the identifier used inside$[elem].Final Answer:
db.collection.updateOne({},{ $set: { 'array.$[elem]': value } }, { arrayFilters: [ { 'elem.field': condition } ] }) -> Option AQuick Check:
Use $set with $[elem] and arrayFilters [OK]
- Using $push instead of $set for updates
- Missing square brackets around identifier
- Not providing arrayFilters option
{ _id: 1, scores: [ { type: 'quiz', score: 5 }, { type: 'exam', score: 8 }, { type: 'quiz', score: 7 } ] }What will be the result of this update?
db.collection.updateOne({ _id: 1 }, { $set: { 'scores.$[elem].score': 10 } }, { arrayFilters: [ { 'elem.type': 'quiz' } ] })What will the
scores array look like after the update?Solution
Step 1: Identify which array elements match the filter
The filter{ 'elem.type': 'quiz' }matches the first and third elements in thescoresarray.Step 2: Apply the update to matched elements only
Thescorefield of these matched elements is set to 10, while the second element remains unchanged.Final Answer:
[ { type: 'quiz', score: 10 }, { type: 'exam', score: 8 }, { type: 'quiz', score: 10 } ] -> Option DQuick Check:
Only 'quiz' type scores updated to 10 [OK]
- Updating all elements ignoring arrayFilters
- Updating wrong elements by misreading filter
- Expecting update without arrayFilters to work
db.collection.updateOne({ _id: 1 }, { $set: { 'items.$[i].status': 'sold' } }, { arrayFilters: [ { 'item.status': 'available' } ] })But no documents are updated. What is the most likely cause?
Solution
Step 1: Check identifier consistency
The update uses$[i]but the arrayFilters usesitem. These must match exactly.Step 2: Understand effect of mismatch
Because the identifiers differ, MongoDB cannot apply the filter, so no elements are updated.Final Answer:
The identifier in arrayFilters does not match the one in the update query. -> Option CQuick Check:
Identifier names must match in update and arrayFilters [OK]
- Using different names for identifier and filter variable
- Assuming $set can't work with $[identifier]
- Blaming query filter without checking arrayFilters
tasks where each task has status and priority. You want to update only tasks with status: 'pending' and priority greater than 5, setting their status to 'in-progress'. Which update command correctly does this?Solution
Step 1: Use a single filter object combining conditions
The arrayFilters option must have one object combining both conditions with commas, meaning AND logic.Step 2: Use correct identifier and update syntax
The update uses$[t]matching the filter identifiert, and$setto update thestatusfield.Final Answer:
db.collection.updateMany({}, { $set: { 'tasks.$[t].status': 'in-progress' } }, { arrayFilters: [ { 't.status': 'pending', 't.priority': { $gt: 5 } } ] }) -> Option BQuick Check:
Combine conditions in one filter object with matching identifier [OK]
- Splitting conditions into multiple filter objects (no AND)
- Using logical operators incorrectly inside arrayFilters
- Using positional $ instead of filtered $[identifier]
Ready to prove it?
Pass the test and this pattern moves unknown
