Definition定义
$replaceRootReplaces the input document with the specified document. The operation replaces all existing fields in the input document, including the用指定的文档替换输入文档。该操作将替换输入文档中的所有现有字段,包括_idfield. You can promote an existing embedded document to the top level, or create a new document for promotion (see example)._id字段。您可以将现有的嵌入式文档提升到顶级,也可以创建新的文档进行提升(参见示例)。Note
You can also use the您还可以使用$replaceWithstage. The$replaceWithstage peforms the same action as the$replaceRootstage, but the stages have different forms.$replaceWith阶段。$replaceWith阶段执行的操作与$replaceRoot阶段相同,但阶段的形式不同。The$replaceRootstage has the following form:$replaceRoot阶段具有以下形式:{ $replaceRoot: { newRoot: <replacementDocument> } }The replacement document can be any valid expression that resolves to a document.替换文档可以是解析为文档的任何有效表达式。The stage errors and fails if如果<replacementDocument>is not a document. For more information on expressions, see Expressions.<replacementDocument>不是文档,则阶段错误并失败。有关表达式的详细信息,请参阅表达式。
Behavior行为
If the 如果<replacementDocument> is not a document, $replaceRoot errors and fails.<replacementDocument>不是文档,$replaceRoot将出错并失败。
If the 如果<replacementDocument> resolves to a missing document (i.e. the document does not exist), $replaceRoot errors and fails. For example, create a collection with the following documents:<replacementDocument>解析为缺少文档(即文档不存在),$replaceRoot将出错并失败。例如,使用以下文档创建一个集合:
db.collection.insertMany([
{ "_id": 1, "name" : { "first" : "John", "last" : "Backus" } },
{ "_id": 2, "name" : { "first" : "John", "last" : "McCarthy" } },
{ "_id": 3, "name": { "first" : "Grace", "last" : "Hopper" } },
{ "_id": 4, "firstname": "Ole-Johan", "lastname" : "Dahl" },
])
Then the following 然后,以下$replaceRoot operation fails because one of the documents does not have the name field:$replaceRoot操作失败,因为其中一个文档没有name字段:
db.collection.aggregate([
{ $replaceRoot: { newRoot: "$name" } }
])
To avoid the error, you can use 为了避免错误,您可以使用$mergeObjects to merge the name document into some default document; for example:$mergeObjects将name文档合并到某个默认文档中;例如:
db.collection.aggregate([
{ $replaceRoot: { newRoot: { $mergeObjects: [ { _id: "$_id", first: "", last: "" }, "$name" ] } } }
])
Alternatively, you can skip the documents that are missing the 或者,您可以跳过缺少name field by including a $match stage to check for existence of the document field before passing documents to the $replaceRoot stage:name字段的文档,方法是在将文档传递给$replaceRoot阶段之前,包含一个$match阶段来检查文档字段的存在:
db.collection.aggregate([
{ $match: { name : { $exists: true, $not: { $type: "array" }, $type: "object" } } },
{ $replaceRoot: { newRoot: "$name" } }
])
Or, you can use 或者,您可以使用$ifNull expression to specify some other document to be root; for example:$ifNull表达式将其他文档指定为根;例如:
db.collection.aggregate([
{ $replaceRoot: { newRoot: { $ifNull: [ "$name", { _id: "$_id", missingName: true} ] } } }
])Examples示例
MongoDB Shell
$replaceRoot with an Embedded Document Field带有嵌入式文档字段
A collection named 名为people contains the following documents:people的集合包含以下文档:
{ "_id" : 1, "name" : "Arlene", "age" : 34, "pets" : { "dogs" : 2, "cats" : 1 } }
{ "_id" : 2, "name" : "Sam", "age" : 41, "pets" : { "cats" : 1, "fish" : 3 } }
{ "_id" : 3, "name" : "Maria", "age" : 25 }
The following operation uses the 以下操作使用$replaceRoot stage to replace each input document with the result of a $mergeObjects operation. $replaceRoot阶段将每个输入文档替换为$mergeObjects操作的结果。The $mergeObjects expression merges the specified default document with the pets document.$mergeObjects表达式将指定的默认文档与pets文档合并。
db.people.aggregate( [
{ $replaceRoot: { newRoot: { $mergeObjects: [ { dogs: 0, cats: 0, birds: 0, fish: 0 }, "$pets" ] }} }
] )
The operation returns the following results:该操作返回以下结果:
{ "dogs" : 2, "cats" : 1, "birds" : 0, "fish" : 0 }
{ "dogs" : 0, "cats" : 1, "birds" : 0, "fish" : 3 }
{ "dogs" : 0, "cats" : 0, "birds" : 0, "fish" : 0 }$replaceRoot with a Document Nested in an Array文档嵌套在数组中
A collection named 名为students contains the following documents:students的集合包含以下文档:
db.students.insertMany([
{
"_id" : 1,
"grades" : [
{ "test": 1, "grade" : 80, "mean" : 75, "std" : 6 },
{ "test": 2, "grade" : 85, "mean" : 90, "std" : 4 },
{ "test": 3, "grade" : 95, "mean" : 85, "std" : 6 }
]
},
{
"_id" : 2,
"grades" : [
{ "test": 1, "grade" : 90, "mean" : 75, "std" : 6 },
{ "test": 2, "grade" : 87, "mean" : 90, "std" : 3 },
{ "test": 3, "grade" : 91, "mean" : 85, "std" : 4 }
]
}
])
The following operation promotes the embedded document(s) with the 以下操作将grade field greater than or equal to 90 to the top level:grade字段大于或等于90的嵌入文档提升到顶级:
db.students.aggregate( [
{ $unwind: "$grades" },
{ $match: { "grades.grade" : { $gte: 90 } } },
{ $replaceRoot: { newRoot: "$grades" } }
] )
The operation returns the following results:该操作返回以下结果:
{ "test" : 3, "grade" : 95, "mean" : 85, "std" : 6 }
{ "test" : 1, "grade" : 90, "mean" : 75, "std" : 6 }
{ "test" : 3, "grade" : 91, "mean" : 85, "std" : 4 }$replaceRoot with a newly created document使用新创建的文档
You can also create new documents as part of the 您还可以在$replaceRoot stage and use them to replace all the other fields.$replaceRoot阶段创建新文档,并使用它们替换所有其他字段。
A collection named 名为contacts contains the following documents:contacts的集合包含以下文档:
{ "_id" : 1, "first_name" : "Gary", "last_name" : "Sheffield", "city" : "New York" }
{ "_id" : 2, "first_name" : "Nancy", "last_name" : "Walker", "city" : "Anaheim" }
{ "_id" : 3, "first_name" : "Peter", "last_name" : "Sumner", "city" : "Toledo" }
The following operation creates a new document out of the 以下操作从first_name and last_name fields.first_name和last_name字段创建新文档。
db.contacts.aggregate( [
{
$replaceRoot: {
newRoot: {
full_name: {
$concat : [ "$first_name", " ", "$last_name" ]
}
}
}
}
] )
The operation returns the following results:该操作返回以下结果:
{ "full_name" : "Gary Sheffield" }
{ "full_name" : "Nancy Walker" }
{ "full_name" : "Peter Sumner" }$replaceRoot with a New Document Created from $$ROOT and a Default Document使用从$$ROOT创建的新文档和默认文档
$$ROOT and a Default DocumentCreate a collection named 使用以下文档创建一个名为contacts with the following documents:contacts的集合:
db.contacts.insertMany( [
{ "_id" : 1, name: "Fred", email: "fred@example.net" },
{ "_id" : 2, name: "Frank N. Stine", cell: "012-345-9999" },
{ "_id" : 3, name: "Gren Dell", home: "987-654-3210", email: "beo@example.net" }
] )
The following operation uses 以下操作使用$replaceRoot with $mergeObjects to output current documents with default values for missing fields:$replaceRoot和$mergeObjects来输出当前文档,并为缺失的字段设置默认值:
db.contacts.aggregate( [
{ $replaceRoot:
{ newRoot:
{ $mergeObjects:
[
{ _id: "", name: "", email: "", cell: "", home: "" },
"$$ROOT"
]
}
}
}
] )
The aggregation returns the following documents:聚合返回以下文档:
{
_id: 1,
name: 'Fred',
email: 'fred@example.net',
cell: '',
home: ''
},
{
_id: 2,
name: 'Frank N. Stine',
email: '',
cell: '012-345-9999',
home: ''
},
{
_id: 3,
name: 'Gren Dell',
email: 'beo@example.net',
cell: '',
home: '987-654-3210'
}C#
The C# examples on this page use the 本页上的C#示例使用Atlas示例数据集中的sample_mflix database from the Atlas sample datasets. sample_mflix数据库。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB .NET/C# Driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB .NET/C#驱动程序文档中的入门。
The following 以下Movie class models the documents in the sample_mflix.movies collection:Movie类对sample_mflix.movies集合中的文档进行建模:
public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[]
public DateTime LastUpdated { get; set; }
}
Note
ConventionPack for Pascal CasePascal大小写的约定包
The C# classes on this page use Pascal case for their property names, but the field names in the MongoDB collection use camel case. To account for this difference, you can use the following code to register a 此页面上的C#类使用Pascal大小写作为其属性名,但MongoDB集合中的字段名使用驼峰大小写。为了解释这种差异,您可以在应用程序启动时使用以下代码注册ConventionPack when your application starts:ConventionPack:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);The following class models 以下类对ImdbData documents:ImdbData文档进行建模:
public class ImdbData
{
public string Id { get; set; }
public int Votes { get; set; }
public float Rating { get; set; }
}
To use the MongoDB .NET/C# driver to add a 要使用MongoDB .NET/C#驱动程序向聚合管道添加$replaceRoot stage to an aggregation pipeline, call the ReplaceRoot() method on a PipelineDefinition object.$replaceRoot阶段,请在PipelineDefinition对象上调用ReplaceRoot()方法。
The following example creates a pipeline stage that replaces each input 以下示例创建了一个管道阶段,该阶段将每个输入的Movie document with the ImdbData document stored in its Imdb property:Movie文档替换为存储在其Imdb属性中的ImdbData文档:
var pipeline = new EmptyPipelineDefinition<Movie>()
.ReplaceRoot(m => m.ImdbData);Node.js
The Node.js examples on this page use the 本页上的Node.js示例使用Atlas示例数据集中的sample_mflix database from the Atlas sample datasets. sample_mflix数据库。To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB Node.js driver documentation.要了解如何创建免费的MongoDB Atlas集群并加载示例数据集,请参阅MongoDB Node.js驱动程序文档中的入门。
To use the MongoDB Node.js driver to add a 要使用MongoDB Node.js驱动程序将$replaceRoot stage to an aggregation pipeline, use the $replaceRoot operator in a pipeline object.$replaceRoot阶段添加到聚合管道中,请在管道对象中使用$replaceRoot运算符。
The following example creates a pipeline stage that replaces each input 以下示例创建了一个管道阶段,将每个输入的movie document with the document stored in its imdb property. The example then runs the aggregation pipeline:movie文档替换为存储在其imdb属性中的文档。然后,该示例运行聚合管道:
const pipeline = [{ $replaceRoot: { newRoot: "$imdb" } }];
const cursor = collection.aggregate(pipeline);
return cursor;Learn More了解更多
To learn more about related pipeline stages, see the 要了解有关相关管道阶段的更多信息,请参阅$replaceRoot guide.$replaceRoot指南。