100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
MongoDB

Updating Documents

Learn how to modify existing documents using updateOne, updateMany, replaceOne, update operators like $set and $inc, and upserts.

CRUD OperationsIntermediate9 min readJul 10, 2026
Analogies

updateOne() and updateMany()

db.collection.updateOne(filter, update) modifies the first document matching filter, while updateMany(filter, update) applies the same modification to every matching document. Both return a result with matchedCount and modifiedCount, which can differ — a document that already has the target value matches the filter but isn't counted as modified since MongoDB detects no actual change.

🏏

Cricket analogy: It is like a scorer correcting one specific dismissal record versus correcting every 'run out' entry across an entire tournament's records — updateOne() touches a single row, updateMany() sweeps every matching row.

Update Operators: $set, $inc, $unset, $push

The update document typically uses operators rather than a plain replacement object: $set assigns new values to specific fields without touching others, $unset removes a field entirely, $inc atomically increments or decrements a numeric field by a given amount, and $push appends a value to an array field ($addToSet does the same but only if the value isn't already present). Passing a plain object without operators to updateOne() actually throws an error, since MongoDB requires update operators for partial modification.

🏏

Cricket analogy: It is like the scorer using $inc to add exactly one run to a batter's tally after every single, rather than retyping the entire scorecard from scratch — targeted operators change only what's needed.

Upserts and replaceOne()

Passing { upsert: true } as an option to updateOne() tells MongoDB to insert a new document built from the filter and update if no document matches, which is useful for idempotent 'create or update' logic without a separate existence check. replaceOne(filter, replacementDoc) is different from updateOne(): it replaces the entire matched document with replacementDoc (except _id), so any fields not present in replacementDoc are lost, unlike $set which only touches the fields you specify.

🏏

Cricket analogy: It is like a scorer who either updates an existing player's profile if it exists or creates a brand-new one on the spot if this is their debut match — upsert avoids a separate 'does this player exist' check.

javascript
// Set fields, increment a counter, and push a new tag
db.products.updateOne(
  { sku: "MOU-2024-BLK" },
  {
    $set: { price: 22.99, lastUpdated: new Date() },
    $inc: { viewCount: 1 },
    $push: { tags: "bestseller" }
  }
);

// Upsert: create the document if no match exists
db.counters.updateOne(
  { _id: "orderSeq" },
  { $inc: { value: 1 } },
  { upsert: true }
);

// Update every matching document at once
db.products.updateMany(
  { category: "clearance" },
  { $set: { discountPercent: 30 } }
);

matchedCount and modifiedCount in an update result can legitimately differ: if updateOne() sets price to 22.99 on a document that already has price 22.99, matchedCount is 1 but modifiedCount is 0, since MongoDB skips writing a field that would be unchanged.

Calling updateOne() or updateMany() with a plain replacement object instead of update operators (e.g. { price: 10 } instead of { $set: { price: 10 } }) throws an error in modern MongoDB drivers, because the driver can't tell whether you meant a partial update or a full replacement. Use replaceOne() if you genuinely want to replace the whole document.

  • updateOne() modifies the first matching document; updateMany() modifies every matching document.
  • $set updates specific fields, $unset removes a field, $inc changes a number atomically, $push appends to an array.
  • matchedCount and modifiedCount can differ when the new value equals the existing value.
  • { upsert: true } inserts a new document from filter and update when no document matches.
  • replaceOne() swaps the entire document body (except _id), unlike operator-based partial updates.
  • Plain replacement objects are rejected by updateOne()/updateMany() — update operators are required.
  • $addToSet appends to an array only if the value isn't already present, avoiding duplicates.

Practice what you learned

Was this page helpful?

Topics covered

#MongoDB#MongoDBStudyNotes#Database#UpdatingDocuments#Updating#Documents#UpdateOne#UpdateMany#StudyNotes#SkillVeris