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.
// 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
1. What happens if you call db.products.updateOne({ sku: "A1" }, { price: 10 }) in a modern MongoDB driver?
2. What does { upsert: true } do when passed to updateOne()?
3. How does replaceOne() differ from updateOne() with $set?
4. Why might matchedCount be 1 while modifiedCount is 0 after an update?
5. What is the difference between $push and $addToSet?
Was this page helpful?
You May Also Like
Querying Documents
Learn how to retrieve documents from MongoDB collections using find() and findOne(), filters, projections, and cursor methods.
Query Operators
Master MongoDB's comparison, logical, element, and array query operators like $gt, $in, $and, $exists, and $elemMatch for precise filtering.
Deleting Documents
Learn how to remove documents from MongoDB collections with deleteOne and deleteMany, and how to safely drop entire collections.