replaceOne()
replaceOne()
Level 3 — CRUD Operations (Create, Read, Update, Delete) The MongoDB collection method used to completely overwrite a single document's payload (excluding its unique
_id) with a new plain document structure.
1. Prerequisites
updateOne()/updateMany()— The partial update alternatives.
2. Term Category
CRUD Operation (Full Document Replacement): replaceOne() replaces the entire content of a single matching document while preserving its original _id primary key.
3. Explanation
Environment Context
- MongoDB Core (Executed inside
mongoshor through drivers. Replaces the target document block on disk, preserving index pointer allocations by keeping the primary key_idimmutable).
(1) Design Motivation — "Why did we design this?"
In application architectures, you occasionally need to reset or overwrite a record completely:
- An integration sync tool fetches a fresh profile from an external API and wants to overwrite whatever local data exists.
- A user completely resets their custom dashboard layout, changing its schema keys.
While you could run updateOne() with $unset to delete all fields followed by $set to write new ones, this is complex and slow.
We designed the replaceOne() method to handle this.
It deletes all existing fields inside the matched document and writes the new plain document structure in their place in a single disk cycle.
The primary key _id is preserved, ensuring any foreign references pointing to the document remain valid.
(2) The Plain Document Requirement
Unlike updateOne(), which requires BSON update operators, replaceOne() requires a plain JSON document as its second argument.
The database parses the object and writes it directly as the new document body.
(3) Reality Metaphor
Imagine managing shipping containers:
updateOne(): Opening the container doors, swapping out 2 crates of parts, and locking it. (Partial update).replaceOne(): Uncoupling the entire Cargo Container from the trailer bed, throwing it away, and coupling a completely new, differently packed container onto the trailer.- The truck's License Plate ID (the
_id) stays bolted to the frame.
- The truck's License Plate ID (the
(4) Code Examples
Overwriting a User Profile Completely
Let's see what happens to Charlie's fields when we run a replacement:
// Start document: Charlie has age, country, and status
db.users.insertOne({
_id: 200,
name: "Charlie",
age: 34,
country: "FR",
status: "pending"
});
// Replace the document (preserves _id: 200)
db.users.replaceOne(
{ _id: 200 },
{ name: "Charles", status: "active" } // Plain document, no operators!
);
db.users.find({ _id: 200 });
// Output (age and country fields are deleted!):
// { "_id": 200, "name": "Charles", "status": "active" }
4. Common Mistakes & Pitfalls
Mistake 1: Utilizing replaceOne() to modify a single field, leading to accidental deletion of other fields in the document
The mistake: Running the query db.users.replaceOne({ _id: 200 }, { status: "suspended" }) in an attempt to freeze an account.
Why it's wrong: The query will succeed, but it will delete all other fields (name, age, email) in Charlie's document, replacing them with just the status field.
This causes immediate, irreversible data loss.
Fix: If you only want to modify a subset of fields, always use updateOne() with the $set operator instead of replaceOne().
// CORRECT (Preserves name, email, age!)
db.users.updateOne({ _id: 200 }, { $set: { status: "suspended" } });
Mistake 2: Using Update Operators ($set, $inc) inside replaceOne() Arguments
The mistake: Calling db.users.replaceOne({ _id: id }, { $set: { name: "Alice" } }) (MongoInvalidArgumentError).
Why it's wrong: replaceOne() expects a replacement DOCUMENT object { name: "Alice" }, NOT update operators ($set). Use updateOne() when using update operators.
Incorrect:
db.users.replaceOne({ _id: id }, { $set: { name: "Alice" } }); // ❌ Cannot use $set in replaceOne!
Fix:
db.users.replaceOne({ _id: id }, { name: "Alice", age: 30 }); // Whole document replacement
Mistake 3: Forgetting that replaceOne() Replaces the Entire Document Object
The mistake: Calling db.users.replaceOne({ _id: id }, { name: "Alice" }) expecting email field to remain.
Why it's wrong: replaceOne() replaces the entire existing document object with the new object, wiping all omitted fields (except _id).
Incorrect:
db.users.replaceOne({ _id: id }, { name: "Alice" }); // ❌ Deletes all other fields!
Fix:
db.users.updateOne({ _id: id }, { $set: { name: "Alice" } }); // Preserves existing fields
5. Practice Exercises
Exercise 1: Entire Document Replacement with replaceOne
Scenario:
Replace an entire document in collection users with a sanitized new document structure while preserving its _id.
Requirements:
- Execute
replaceOne({ _id: targetId }, newDocument).
Answer
Implementation
const targetId = new ObjectId("60c72b2f9b1d8b2c88888880");
db.users.replaceOne(
{ _id: targetId },
{
name: "Alice Smith",
email: "alice.smith@example.com",
status: "verified",
updatedAt: new Date()
}
);
Technical Explanation
replaceOne()completely replaces document content with the new replacement document object.- The original
_idprimary key is automatically preserved. - Any unmentioned fields in the original document are removed.
Exercise 2: Upserting Replacement Documents
Scenario:
Replace a user setting document if it exists, or insert a default settings document if missing using upsert: true.
Requirements:
- Execute
replaceOne()with{ upsert: true }.
Answer
Implementation
db.user_settings.replaceOne(
{ userId: new ObjectId("60c72b2f9b1d8b2c88888880") },
{
userId: new ObjectId("60c72b2f9b1d8b2c88888880"),
theme: "dark",
notifications: true
},
{ upsert: true }
);
Technical Explanation
upsert: trueinserts the replacement document if no document matches the query filter.- Ideal for state synchronization endpoints receiving full entity payloads.
- Atomic replace-or-insert operation.
Exercise 3: Validating Replacement Document Constraints
Scenario:
Explain why replacement documents passed to replaceOne() CANNOT contain update operators like $set.
Requirements:
- Describe replacement document restriction.
Answer
Implementation
// ❌ Invalid replaceOne syntax (throws error):
// db.users.replaceOne({ _id: id }, { $set: { name: "Alice" } });
// ✅ Correct replaceOne syntax (plain document):
db.users.replaceOne({ _id: id }, { name: "Alice", email: "alice@example.com" });
Technical Explanation
replaceOne()expects a plain BSON document representation without$setor$incoperators.- Use
updateOne()when applying targeted atomic update operators. - Prevents ambiguous operation intent.
6. Related Terms
updateOne()/updateMany()— Partial update methods.$setvs. Whole-Document Replacement — Comparative rules.
7. Key Takeaways
replaceOne()completely overwrites a document's fields.- Preserves the original, immutable primary key
_idof the document. - Expects a plain JSON document as the second argument; operators are forbidden.
- Any fields omitted from the replacement document are deleted on disk.
- Never use
replaceOneto edit single fields, as it will wipe out other data. - Use
updateOne+$setfor partial edits; usereplaceOnefor complete resets.