Update Specific Items in a MongoDB Array Using $[identifier]
📖 Scenario: You manage a MongoDB collection that stores information about books in a library. Each book document contains an array of reviews, where each review has a reviewer name and a rating score.Sometimes, you need to update the rating given by a specific reviewer without changing other reviews.
🎯 Goal: Learn how to update only the reviews in the reviews array where the reviewer matches a specific name, using the $[identifier] filtered positional operator in MongoDB.
📋 What You'll Learn
Create a MongoDB document with a reviews array containing multiple review objects.
Define an array filter to target reviews by a specific reviewer name.
Use the $[identifier] filtered positional operator to update only the matching review's rating.
Complete the update operation with the correct filter and update syntax.
💡 Why This Matters
🌍 Real World
Updating specific items in arrays is common in applications like product reviews, user comments, or order items where only certain entries need changes without affecting others.
💼 Career
Knowing how to use array filters and the $[identifier] operator is essential for backend developers and database administrators working with MongoDB to write efficient and precise update queries.
Progress0 / 4 steps
1
Create a book document with a reviews array
Create a MongoDB document called book with the following fields: title set to "Learn MongoDB", and reviews as an array containing these objects exactly: { reviewer: "Alice", rating: 4 }, { reviewer: "Bob", rating: 5 }, and { reviewer: "Charlie", rating: 3 }.
MongoDB
Hint
Define a constant book with the exact structure and values for title and reviews.
2
Define an array filter to target Bob's review
Create a variable called arrayFilters that is an array containing one filter object. This filter object should use the identifier elem and match reviews where elem.reviewer equals "Bob".
MongoDB
Hint
Use const arrayFilters = [{ "elem.reviewer": "Bob" }]; to define the filter.
3
Write the update command using $[elem] to change Bob's rating
Write a MongoDB update command called updateCommand that uses $set to change reviews.$[elem].rating to 10. Use the arrayFilters variable you defined earlier in the update options.
MongoDB
Hint
Use $set with the path reviews.$[elem].rating to update the rating.
4
Combine filter, update, and arrayFilters in the final update operation
Write a variable called finalUpdate that is an object containing these keys: filter to find the book by title "Learn MongoDB", update set to updateCommand, and options set to an object with arrayFilters equal to the arrayFilters variable.
MongoDB
Hint
Combine the filter, update, and options with arrayFilters into one object called finalUpdate.
Practice
(1/5)
1. What does the $[identifier] syntax do in a MongoDB update operation?
easy
A. It updates only the array elements that match the filter specified in arrayFilters.
B. It deletes the entire array from the document.
C. It adds a new element to the array without any condition.
D. It replaces the whole document with a new one.
Solution
Step 1: Understand $[identifier] usage
The $[identifier] syntax is used to target specific elements inside an array during an update.
Step 2: Role of arrayFilters
The arrayFilters option 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 in arrayFilters. -> Option A
Quick Check:
$[identifier] updates filtered array items [OK]
Hint: Remember: $[id] updates filtered array elements only [OK]
Common Mistakes:
Thinking $[identifier] updates the whole array
Confusing $[identifier] with $push or $set without filters
Ignoring the need for arrayFilters option
2. Which of the following is the correct syntax to update array elements using $[elem] with arrayFilters in MongoDB?
easy
A. db.collection.updateOne({},{ $set: { 'array.$[elem]': value } }, { arrayFilters: [ { 'elem.field': condition } ] })
B. db.collection.updateOne({},{ $push: { 'array.$[elem]': value } }, { arrayFilters: [ { 'elem.field': condition } ] })
C. db.collection.updateOne({},{ $set: { 'array.$elem': value } }, { arrayFilters: [ { 'elem.field': condition } ] })
D. db.collection.updateOne({},{ $set: { 'array.$[elem]': value } })
Solution
Step 1: Identify correct update operator and syntax
The $set operator is used to update existing fields. The positional filtered identifier must be inside square brackets like $[elem].
Step 2: Confirm usage of arrayFilters
The arrayFilters option 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 A
Quick Check:
Use $set with $[elem] and arrayFilters [OK]
Hint: Use $set with $[identifier] and arrayFilters together [OK]
But no documents are updated. What is the most likely cause?
medium
A. The $set operator cannot be used with $[i].
B. The query filter {_id: 1} is incorrect.
C. The identifier in arrayFilters does not match the one in the update query.
D. MongoDB does not support arrayFilters in updateOne.
Solution
Step 1: Check identifier consistency
The update uses $[i] but the arrayFilters uses item. 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 C
Quick Check:
Identifier names must match in update and arrayFilters [OK]
Hint: Match identifier names exactly in update and arrayFilters [OK]
Common Mistakes:
Using different names for identifier and filter variable
Assuming $set can't work with $[identifier]
Blaming query filter without checking arrayFilters
5. You have documents with an array field 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?