Replacing Documents with replaceOne()

The replaceOne() method replaces the contents of the first document matching a filter with a replacement document.

Basic syntax

db.collection.replaceOne(
  filter,
  replacement,
  options
)

Unlike a modifier update, a replacement document does not contain operators such as $set at the top level. It describes the new non-identifier contents of the document.

Example

Original document:

{
  _id: 1,
  name: "Arun",
  age: 22,
  city: "Chennai",
  active: true
}

Replacement:

db.users.replaceOne(
  { _id: 1 },
  {
    name: "Arun",
    age: 23
  }
);

The resulting document contains _id, name, and age. The previous city and active fields are removed.

The immutable _id field cannot ordinarily be changed through a replacement. If the replacement supplies an _id, it must satisfy the operation's identifier constraints.

When replacement is appropriate

Replacement can be useful when the application has constructed the complete intended document and deliberately wants to discard the previous non-identifier fields.

It is riskier when multiple application versions write different subsets of fields or when the document contains fields that the caller does not know about.

Update versus replacement

Use updateOne() with $set when changing selected fields.

Use replaceOne() when intentionally replacing the document's non-identifier contents.

Upsert with replacement

replaceOne() also supports an upsert option. If no document matches the filter, MongoDB can insert a new document based on the replacement and filter behavior, subject to the operation's rules.

An upsert is not a universal substitute for a carefully designed unique key. Concurrent operations and filter design must be considered when uniqueness is important.

Compare update and replacement behavior
db.replaceDemo.insertOne({
  _id: 1,
  name: "Arun",
  age: 22,
  city: "Chennai",
  active: true
});

// Modifier update: other fields remain.
db.replaceDemo.updateOne(
  { _id: 1 },
  { $set: { age: 23 } }
);

// Replacement: unspecified non-_id fields are removed.
db.replaceDemo.replaceOne(
  { _id: 1 },
  { name: "Arun", age: 24 }
);

db.replaceDemo.findOne({ _id: 1 });
💡 The modifier update changes the age while retaining other fields. The replacement operation then replaces the document's non-_id contents, removing city and active.
Key Takeaways
  • replaceOne() replaces the first matching document's non-_id contents.
  • A replacement document is not a modifier update document.
  • Unspecified fields are removed during replacement.
  • The _id field is immutable in ordinary replacement operations.
  • Use replacement only when the complete intended document is known.
Knowledge Check

What is the main risk of using replaceOne() when you only want to update a user's age?