Updating Documents

beginner
12 min

Updating Documents

Data rarely stays still: prices change, stock levels move, users edit their profiles. MongoDB modifies documents in place with updateOne, updateMany, and a family of update operators that let you change exactly the fields you need without rewriting the whole document. This CodeYourCraft lesson walks through the operators you will use every day, plus upserts and findOneAndUpdate.

updateOne and updateMany

Both methods take a filter (which documents) and an update document (what to change). updateOne modifies the first match; updateMany modifies all matches:

javascript
use shop db.products.updateOne( { name: 'Desk Lamp' }, { $set: { price: 1399 } } ) // { matchedCount: 1, modifiedCount: 1 } db.products.updateMany( { tags: 'clearance' }, { $set: { onSale: true } } )

The result distinguishes matchedCount from modifiedCount: a document that already had price 1399 would match but not be modified. Update documents must use operators; passing a plain document to updateOne is an error, which protects you from accidentally replacing an entire document.

The Everyday Operators: $set, $unset, $rename

javascript
db.customers.updateOne( { email: 'arjun@example.com' }, { $set: { 'address.city': 'Mumbai', tier: 'gold' }, // create or overwrite $unset: { legacyCode: '' }, // remove a field $rename: { loyaltyPoints: 'points' } // rename a field } )

$set creates fields that do not exist yet, including nested paths, which makes it the workhorse of schema evolution.

Numeric Operators: $inc, $mul, $min, $max

Counters and prices should be changed atomically on the server, never read-modify-written from the client:

javascript
db.products.updateOne({ _id: 'SKU-1001' }, { $inc: { 'stock.warehouse': -1 } }) db.products.updateMany({ tags: 'audio' }, { $mul: { price: 0.9 } }) // 10% off db.products.updateOne({ _id: 'SKU-1001' }, { $min: { price: 449 } }) // only lowers db.products.updateOne({ _id: 'SKU-1001' }, { $max: { highestBid: 700 } })

Because each update is atomic per document, two simultaneous $inc operations never lose an increment.

Array Operators: $push, $pull, $addToSet

javascript
db.products.updateOne({ _id: 'SKU-1001' }, { $push: { reviews: { user: 'Neha', stars: 5 } } }) db.products.updateOne({ _id: 'SKU-1001' }, { $addToSet: { tags: 'bestseller' } }) // no duplicates db.products.updateOne({ _id: 'SKU-1001' }, { $pull: { tags: 'clearance' } }) // remove matches

To update one element inside an array, the positional operator $ refers to the first element matched by the filter:

javascript
db.products.updateOne( { 'reviews.user': 'Neha' }, { $set: { 'reviews.$.stars': 4 } } )

Upserts: Update or Insert

With upsert: true, MongoDB inserts a new document when the filter matches nothing, combining the filter fields with the update operators:

javascript
db.counters.updateOne( { _id: 'pageviews' }, { $inc: { total: 1 } }, { upsert: true } )

This one-liner initializes the counter on first use and increments it forever after, with no race conditions.

findOneAndUpdate

When you need the document back in the same atomic step, use findOneAndUpdate with returnDocument: 'after' to receive the updated version. It is the standard tool for job queues and sequence generators.

Key Takeaways

  • updateOne changes the first match; updateMany changes all matches.
  • $set, $unset, and $rename handle everyday field changes.
  • $inc, $mul, $min, and $max modify numbers atomically on the server.
  • $push, $addToSet, $pull, and the positional $ manage arrays in place.
  • upsert: true turns an update into insert-if-missing, ideal for counters.

In the next lesson we complete CRUD by learning to delete documents safely.

Updating Documents - MongoDB | CodeYourCraft | CodeYourCraft