$replaceRoot is a MongoDB aggregation stage that replaces the whole input document with newRoot. Use it to promote an embedded document to the top level, or to emit a newly built document shape.
Remember
$replaceRoot = swap the whole document
{ $replaceRoot: { newRoot: <document expression> } }
newRoot must resolve to a document
(missing / non-document → error)
Common:
newRoot: "$name" // promote nested object
newRoot: { full: ... } // build a new object
vs $replaceWith → same job, shorter form
vs $project → reshape fields vs replace entire root
A string, number, or array is not valid. Promote an object field, or build { ... }.
_id
Original _id is discarded
Unless you copy it into newRoot, the output has no outer _id (or uses one from the nested doc).
vs project
Need fields from the outer doc? Plan ahead
After promote, outer fields are gone. Merge them into newRoot first, or use $project if you only need a reshape.
Analysis
Performance Notes
Approach
Cost
Best for
Promote one nested field
Per document
Flatten embedded objects for APIs
$match then replace
Filter first
Skip docs that would error
$unwind + replace
More docs
One root per array element
Prefer $match before $replaceRoot when some documents lack the nested field. Pairing with $unwind multiplies documents—use it only when you need that shape.
Remember
Key Takeaways
Role: replace the whole document with newRoot.
Must be a document: missing or non-document values error.
Alias:$replaceWith is the same operation in shorter form.
vs $project: swap the root vs reshape fields on the current doc.
One line:$replaceRoot answers “what document should leave this stage instead of the current one?”
Frequently Asked Questions
$replaceRoot replaces the entire input document with a new document from newRoot. newRoot must resolve to a document—often an embedded field like $name, or a newly built object.
They do the same job. $replaceRoot uses { newRoot: <expression> }. $replaceWith takes the expression directly: { $replaceWith: <expression> }. Pick the form that reads clearer.
The old document—including _id—is discarded. Keep _id only if you put it in newRoot, for example with $mergeObjects or by setting _id: "$_id".
The stage errors. Guard with $ifNull, merge defaults via $mergeObjects, or $match for field existence before $replaceRoot.
$project reshapes fields on the current document. $replaceRoot throws away the outer document and substitutes newRoot as the whole document. Use it to flatten a nested object to the top level.
When each array element should become its own root document. $unwind first, then $replaceRoot: { newRoot: "$arrayField" }.