MongoDB聚合中$replaceRoot的反向操作实现方法
将MongoDB根文档封装到子文档的聚合实现
需求说明
已知MongoDB的$replaceRoot聚合阶段可将子文档提升至根层级,例如:
{ "name": "John Doe", "address": { "city": "Prague", "zip": "15000" } } -> { "city": "Prague", "zip": "15000" }
现在需要实现反向操作:把整个根文档封装到指定子文档中,示例如下:
{ "name": "John Doe", "address": { "city": "Prague", "zip": "15000" } } -> { "person": { "name": "John Doe", "address": { "city": "Prague", "zip": "15000" } } }
可行的聚合实现方案
核心是利用MongoDB聚合中的$$ROOT变量(代表当前聚合阶段的根文档),有两种简洁的实现方式:
方案1:使用$replaceRoot(或别名$replaceWith)
$replaceRoot可直接替换根文档为新构造的文档,只需将$$ROOT赋值给目标子字段即可:
db.collection.aggregate([ { $replaceRoot: { newRoot: { person: "$$ROOT" } } } ])
使用更简洁的别名$replaceWith,代码如下:
db.collection.aggregate([ { $replaceWith: { person: "$$ROOT" } } ])
方案2:使用$project
通过$project构造新文档,将$$ROOT赋值给目标子字段,还可按需控制是否保留原_id:
db.collection.aggregate([ { $project: { person: "$$ROOT", _id: 0 // 若需保留原_id,可移除该行 } } ])
注意事项
- 原文档的
_id字段会被默认封装到子文档中,若不需要可通过$project显式排除,或在$replaceRoot构造新文档时单独处理。 $$ROOT会引用当前阶段的完整文档,无论根文档结构如何,都能实现完整封装。
内容的提问来源于stack exchange,提问作者Patrik Šimunič
相关产品推荐
相关产品推荐

