Bird
Raised Fist0
MongoDBquery~5 mins

Array update with positional $ operator in MongoDB

Choose your learning style10 modes available
Introduction

The positional $ operator helps you update a specific item inside an array in a document without changing the whole array.

You want to change the price of a specific product in a shopping cart array.
You need to update the status of a particular task inside a list of tasks.
You want to fix a typo in one comment inside an array of comments.
You want to mark one item as completed in a list of to-do items.
Syntax
MongoDB
db.collection.updateOne(
  { "arrayField.identifier": value },
  { $set: { "arrayField.$.fieldToUpdate": newValue } }
)

The query part finds the document with the array item matching the condition.

The $ in arrayField.$ means the first matched array element.

Examples
Updates the quantity of the first item with productId 123 in the items array.
MongoDB
db.orders.updateOne(
  { "items.productId": 123 },
  { $set: { "items.$.quantity": 5 } }
)
Marks the step with stepId 10 as done in the steps array.
MongoDB
db.tasks.updateOne(
  { "steps.stepId": 10 },
  { $set: { "steps.$.status": "done" } }
)
Changes the email address in the contacts array where type is email.
MongoDB
db.users.updateOne(
  { "contacts.type": "email" },
  { $set: { "contacts.$.value": "newemail@example.com" } }
)
Sample Program

This example inserts a document with an array of items. Then it updates the quantity of the item with sku 'def' to 50 using the positional $ operator.

MongoDB
db.inventory.insertOne({
  _id: 1,
  items: [
    { sku: "abc", qty: 10 },
    { sku: "def", qty: 20 },
    { sku: "xyz", qty: 30 }
  ]
})

print('Before update:')
printjson(db.inventory.findOne({_id: 1}))

// Update qty of item with sku 'def' to 50

const updateResult = db.inventory.updateOne(
  { "items.sku": "def" },
  { $set: { "items.$.qty": 50 } }
)

print('Update result:')
printjson(updateResult)

print('After update:')
printjson(db.inventory.findOne({_id: 1}))
OutputSuccess
Important Notes

The positional $ operator updates only the first matching array element.

If no array element matches, no update happens.

Use updateOne to update a single document, or updateMany to update multiple documents.

Summary

The positional $ operator lets you update one matching item inside an array.

You find the document and array element by a query, then use $set with arrayField.$.

This is useful to change just one part of an array without replacing the whole array.

Practice

(1/5)
1.

What does the positional $ operator do in a MongoDB update?

easy
A. It updates the first matching element in an array field.
B. It deletes the entire array field.
C. It adds a new element to the array.
D. It replaces the whole document.

Solution

  1. Step 1: Understand the positional operator usage

    The $ operator targets the first array element that matches the query condition.
  2. Step 2: Recognize update effect

    It updates only that matched element without changing other array elements or the whole array.
  3. Final Answer:

    It updates the first matching element in an array field. -> Option A
  4. Quick Check:

    Positional $ updates one array item [OK]
Hint: Positional $ updates only the first matched array element [OK]
Common Mistakes:
  • Thinking $ replaces the whole array
  • Confusing $ with $push or $pop
  • Assuming it updates all matching elements
2.

Which of the following is the correct syntax to update the first matching element in the scores array where score is 85?

db.students.updateOne(
  { "scores.score": 85 },
  { $set: { "scores.$.score": 90 } }
)
easy
A. db.students.updateOne({ "scores.score": 85 }, { $set: { "scores.score": 90 } })
B. db.students.updateOne({ "scores.$.score": 85 }, { $set: { "scores.$.score": 90 } })
C. db.students.updateOne({ "scores.score": 85 }, { $set: { "scores.$.score": 90 } })
D. db.students.updateOne({ "scores.$.score": 85 }, { $set: { "scores.score": 90 } })

Solution

  1. Step 1: Identify the query filter

    The filter must be on the array field without the positional operator: { "scores.score": 85 }.
  2. Step 2: Use positional operator in update

    The update uses "scores.$.score" to update the matched element's score.
  3. Final Answer:

    db.students.updateOne({ "scores.score": 85 }, { $set: { "scores.$.score": 90 } }) -> Option C
  4. Quick Check:

    Query without $; update with scores.$ [OK]
Hint: Use $ only in update path, not in query filter [OK]
Common Mistakes:
  • Using $ in the query filter
  • Not using $ in the update path
  • Updating the whole array instead of one element
3.

Given the document:

{ _id: 1, items: [ { name: "apple", qty: 5 }, { name: "banana", qty: 3 } ] }

What will be the document after running this update?

db.collection.updateOne(
  { _id: 1, "items.name": "banana" },
  { $set: { "items.$.qty": 10 } }
)
medium
A. { _id: 1, items: [ { name: "apple", qty: 5 }, { name: "banana", qty: 10 } ] }
B. { _id: 1, items: [ { name: "apple", qty: 10 }, { name: "banana", qty: 3 } ] }
C. { _id: 1, items: [ { name: "apple", qty: 5 }, { name: "banana", qty: 3 }, { name: "banana", qty: 10 } ] }
D. { _id: 1, items: [ { name: "apple", qty: 5 } ] }

Solution

  1. Step 1: Find matching array element

    The query matches document with _id 1 and array element where name is "banana".
  2. Step 2: Update matched element's qty

    The positional operator $ updates the qty of the matched "banana" element to 10.
  3. Final Answer:

    { _id: 1, items: [ { name: "apple", qty: 5 }, { name: "banana", qty: 10 } ] } -> Option A
  4. Quick Check:

    Only matched array element qty changed [OK]
Hint: Positional $ updates only matched array element [OK]
Common Mistakes:
  • Updating wrong array element
  • Adding new element instead of updating
  • Replacing entire array
4.

What is wrong with this update query?

db.orders.updateOne(
  { "products.$.id": 123 },
  { $set: { "products.$.quantity": 5 } }
)
medium
A. Using positional operator $ in the query filter is invalid.
B. Both A and C are correct.
C. The query filter should use products.id without $.
D. The $set operator cannot update array elements.

Solution

  1. Step 1: Check query filter syntax

    The positional operator $ cannot be used in the query filter path; it must be omitted.
  2. Step 2: Correct query filter

    The filter should be { "products.id": 123 } to find the matching array element.
  3. Final Answer:

    Both A and C are correct. -> Option B
  4. Quick Check:

    No $ in query filter; only in update path [OK]
Hint: Never use $ in query filter, only in update path [OK]
Common Mistakes:
  • Using $ in query filter
  • Confusing query filter and update syntax
  • Assuming $set can't update arrays
5.

You have documents like:

{ _id: 1, tags: [ { name: "urgent", status: "open" }, { name: "review", status: "closed" } ] }

Write an update query to change the status of the tag with name "review" to "open" using the positional $ operator.

hard
A. db.collection.updateOne({ "tags.name": "review" }, { $set: { "tags.$.name": "open" } })
B. db.collection.updateOne({ "tags.$.name": "review" }, { $set: { "tags.status": "open" } })
C. db.collection.updateOne({ "tags.name": "review" }, { $set: { "tags.status": "open" } })
D. db.collection.updateOne({ "tags.name": "review" }, { $set: { "tags.$.status": "open" } })

Solution

  1. Step 1: Use correct query filter

    The filter should find the document with an array element where tags.name is "review".
  2. Step 2: Use positional operator in update

    The update uses tags.$.status to update the matched tag's status to "open".
  3. Final Answer:

    db.collection.updateOne({ "tags.name": "review" }, { $set: { "tags.$.status": "open" } }) -> Option D
  4. Quick Check:

    Query on tags.name; update tags.$.status [OK]
Hint: Match array element in query; update with tags.$.field [OK]
Common Mistakes:
  • Using $ in query filter path
  • Updating wrong field in array
  • Not using positional operator in update
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard