MongoDB $replaceWith Stage

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $replaceWith?

$replaceWith is a MongoDB aggregation stage that replaces the whole input document with an expression result. It does the same job as $replaceRoot, with a shorter form.

Remember
$replaceWith = $replaceRoot, shorter syntax

{ $replaceWith: <document expression> }

Same as:
{ $replaceRoot: { newRoot: <document expression> } }

expression must resolve to a document
(missing / non-document → error)

Common:
  { $replaceWith: "$name" }
  { $replaceWith: { full_name: ... } }

vs $project → swap entire root vs reshape fields
UsePrefer
Short promote / rebuild root$replaceWith
Explicit newRoot label$replaceRoot
Keep outer doc; pick fields$project

How to Use $replaceWith in MongoDB

Choose the replacement document, ensure it always exists, then use the short stage form.

  1. Decide the new document—a field path like "$name", or a built object.
  2. Optional: $match so every document has that nested field.
  3. Add { $replaceWith: <expression> }.
  4. If you still need _id or defaults, merge with $mergeObjects or guard with $ifNull.
PieceRequired?Role
ExpressionYesMust resolve to a document
Field pathCommonPromote an embedded object (e.g. "$name")
Built objectOptionalCreate a fresh document shape

Pseudocode

Pseudocode
for each document:
    next = evaluate(expression)
    if next is missing or not a document:
        error
    emit next   // old fields (including _id) are gone

// same result as $replaceRoot { newRoot: expression }

Cheat Sheet

Keep these facts handy while swapping document roots.

TopicDetail
TypeAggregation stage (MongoDB 4.2+)
Syntax{ $replaceWith: <expression> }
Equivalent{ $replaceRoot: { newRoot: <expression> } }
Promote nested{ $replaceWith: "$name" }
Build new{ $replaceWith: { full_name: { $concat: [...] } } }
Missing fieldErrors—use $match, $ifNull, or $mergeObjects
With arrays$unwind then { $replaceWith: "$item" }

Live Preview

Pick a replacement style and see how one person document changes.

Simulates $replaceWith on { _id: 1, name: { first: "Grace", last: "Hopper" }, city: "NY" }.

Result
$replaceWith: "$name"

output:
  { first: "Grace", last: "Hopper" }

Worked Walkthrough — Promote Nested Name

A person document wraps first / last inside name. Goal: make that nested object the whole document, using the short stage form.

Calculation
Document in:
  { _id: 1, name: { first: "Grace", last: "Hopper" }, city: "NY" }

$replaceWith: "$name"

Same as:
$replaceRoot: { newRoot: "$name" }

Document out:
  { first: "Grace", last: "Hopper" }

Note: _id and city are gone unless you merge them in

MongoDB Examples

Insert sample people, promote a nested name, then build a new root. Run these in mongosh in order.

Example 1 — Sample Data

Two people with a nested name object and a city field.

mongosh
db.people.insertMany([
  {
    _id: 1,
    name: { first: "Grace", last: "Hopper" },
    city: "NY"
  },
  {
    _id: 2,
    name: { first: "Alan", last: "Turing" },
    city: "London"
  }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in people. Run find() to see them:

mongosh
db.people.find()

Read each document like this:

FieldExamplePlain English
name{ first, last }Nested name object
city"NY"City (dropped when promoting name)

How It Works

  1. Insert once. insertMany adds two people.
  2. Name is nested. first and last live under name.
  3. Ready to replace. The next examples use $replaceWith.

Example 2 — Promote Nested Document

Goal: make name the entire output document (outer _id and city are discarded).

mongosh
db.people.aggregate([
  { $replaceWith: "$name" }
]);

How It Works

  1. Evaluate the expression. "$name" resolves to the nested object.
  2. Swap the root. That object becomes the whole document.
  3. Outer fields are gone. Previous _id and city are not kept.
  4. Shorter than $replaceRoot. Equivalent to { $replaceRoot: { newRoot: "$name" } }.

Example 3 — Build a New Root

Goal: create a fresh document with full_name from first and last, and keep the original _id.

mongosh
db.people.aggregate([
  {
    $replaceWith: {
      _id: "$_id",
      full_name: {
        $concat: ["$name.first", " ", "$name.last"]
      }
    }
  }
]);

How It Works

  1. Build an object. The stage argument is a new document, not only a field path.
  2. Keep _id. _id: "$_id" copies the original id into the new root.
  3. Concat names. $concat joins name.first, a space, and name.last.
  4. Everything else is dropped. Nested name and city do not appear unless you add them.

Edge Cases & Pitfalls

Check these before using $replaceWith in production pipelines.

missing

Missing expression fails the stage

If the field path is absent, aggregation errors. Use $match, $ifNull, or $mergeObjects with defaults.

type

Result must be a document

A string, number, or array is not valid. Promote an object field, or build { ... }.

_id

Original _id is discarded

Unless you copy it into the replacement document, the output has no outer _id (or uses one from the nested doc).

alias

Not a different stage behavior

$replaceWith and $replaceRoot are aliases in effect. Switching forms does not change results.

Performance Notes

ApproachCostBest for
Promote one nested fieldPer documentFlatten embedded objects for APIs
$match then replaceFilter firstSkip docs that would error
$unwind + replaceMore docsOne root per array element

Cost matches $replaceRoot. Prefer $match first when some documents lack the nested field. Pair with $unwind only when you need one document per array element.

Key Takeaways

  • Role: replace the whole document with one expression result.
  • Shorthand: same as $replaceRoot without the newRoot wrapper.
  • Must be a document: missing or non-document values error.
  • vs $project: swap the root vs reshape fields on the current doc.

One line: $replaceWith is the short way to say “make this expression the whole document.”

Frequently Asked Questions

$replaceWith replaces the entire input document with a document from a single expression. Behavior matches $replaceRoot—promote a nested object or emit a newly built document.
Same operation, shorter form. $replaceRoot uses { newRoot: <expression> }. $replaceWith is { $replaceWith: <expression> }. Choose the form that reads clearer.
The old document—including _id—is discarded unless you put _id in the replacement expression.
The stage errors. Guard with $match, $ifNull, or $mergeObjects with defaults before or inside $replaceWith.
MongoDB 4.2 added $replaceWith as a shorthand for $replaceRoot. Both remain supported.
$project reshapes fields on the current document. $replaceWith discards the outer document and substitutes the expression result as the whole document.

Next: $sample

Randomly select a fixed number of documents from the pipeline.

$sample tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful