Docs Menu
Docs Home
/ /

$replaceRoot (etapa de agregación)

$replaceRoot

Reemplaza el documento de entrada por el documento especificado. La operación reemplaza todos los campos existentes en el documento de entrada, incluido el campo _id. Puede promover un documento incrustado existente al nivel superior o crear un nuevo documento para promoverlo (consulte ejemplo).

Nota

También puedes utilizar el $replaceWith Etapa. La etapa realiza la $replaceWith $replaceRoot misma acción que la etapa, pero las etapas tienen formas diferentes.

La etapa $replaceRoot tiene el siguiente formato:

{ $replaceRoot: { newRoot: <replacementDocument> } }

El documento de reemplazo puede ser cualquier expresión válida que se resuelva en un documento. La etapa presenta errores y falla si <replacementDocument> no es un documento. Para obtener más información sobre expresiones, consulta Expresiones.

Si el <replacementDocument> no es un documento, $replaceRoot produce errores y falla.

Si el <replacementDocument> se resuelve en un documento inexistente (es decir, el documento no existe), $replaceRoot genera un error y falla. Por ejemplo, crea una colección con los siguientes documentos:

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" },
])

Entonces la siguiente $replaceRoot operación falla porque uno de los documentos no tiene el campo name:

db.collection.aggregate([
{ $replaceRoot: { newRoot: "$name" } }
])

Para evitar el error, puedes usar $mergeObjects para fusionar el documento name en algún documento por defecto; por ejemplo:

db.collection.aggregate([
{ $replaceRoot: { newRoot: { $mergeObjects: [ { _id: "$_id", first: "", last: "" }, "$name" ] } } }
])

Alternativamente, puede omitir los documentos que no tienen el campo name incluyendo una etapa $match para verificar la existencia del campo del documento antes de pasar los documentos a la etapa $replaceRoot:

db.collection.aggregate([
{ $match: { name : { $exists: true, $not: { $type: "array" }, $type: "object" } } },
{ $replaceRoot: { newRoot: "$name" } }
])

O bien, puede usar la expresión $ifNull para especificar algún otro documento como raíz; por ejemplo:

db.collection.aggregate([
{ $replaceRoot: { newRoot: { $ifNull: [ "$name", { _id: "$_id", missingName: true} ] } } }
])

Una colección llamada people contiene los siguientes documentos:

{ "_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 }

La siguiente operación utiliza la etapa $replaceRoot para reemplazar cada documento de entrada con el resultado de una operación $mergeObjects. La expresión $mergeObjects fusiona el documento por defecto especificado con el documento pets.

db.people.aggregate( [
{ $replaceRoot: { newRoot: { $mergeObjects: [ { dogs: 0, cats: 0, birds: 0, fish: 0 }, "$pets" ] }} }
] )

La operación devuelve los siguientes resultados:

{ "dogs" : 2, "cats" : 1, "birds" : 0, "fish" : 0 }
{ "dogs" : 0, "cats" : 1, "birds" : 0, "fish" : 3 }
{ "dogs" : 0, "cats" : 0, "birds" : 0, "fish" : 0 }

Una colección llamada students contiene los siguientes documentos:

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 }
]
}
])

La siguiente operación promueve los documentos incrustados con el campo grade que son mayores o iguales a 90 al nivel superior:

db.students.aggregate( [
{ $unwind: "$grades" },
{ $match: { "grades.grade" : { $gte: 90 } } },
{ $replaceRoot: { newRoot: "$grades" } }
] )

La operación devuelve los siguientes resultados:

{ "test" : 3, "grade" : 95, "mean" : 85, "std" : 6 }
{ "test" : 1, "grade" : 90, "mean" : 75, "std" : 6 }
{ "test" : 3, "grade" : 91, "mean" : 85, "std" : 4 }

También puedes crear nuevos documentos como parte de la fase $replaceRoot y usarlos para reemplazar todos los demás campos.

Una colección llamada contacts contiene los siguientes documentos:

{ "_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" }

La siguiente operación crea un nuevo documento a partir de los campos first_name y last_name.

db.contacts.aggregate( [
{
$replaceRoot: {
newRoot: {
full_name: {
$concat : [ "$first_name", " ", "$last_name" ]
}
}
}
}
] )

La operación devuelve los siguientes resultados:

{ "full_name" : "Gary Sheffield" }
{ "full_name" : "Nancy Walker" }
{ "full_name" : "Peter Sumner" }

Cree una colección llamada contacts con los siguientes documentos:

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" }
] )

La siguiente operación utiliza $replaceRoot junto con $mergeObjects para generar los documentos actuales con valores por defecto para los campos faltantes:

db.contacts.aggregate( [
{ $replaceRoot:
{ newRoot:
{ $mergeObjects:
[
{ _id: "", name: "", email: "", cell: "", home: "" },
"$$ROOT"
]
}
}
}
] )

La agregación devuelve los siguientes documentos:

{
_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'
}

Los ejemplos de C# en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulta Primeros pasos en la documentación del controlador de MongoDB .NET/C#.

La siguiente clase Movie modela los documentos en la colección 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; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

Nota

ConventionPack para Pascal Case

Las clases de C# en esta página utilizan Pascal case para los nombres de sus propiedades, pero los nombres de los campos en la colección de MongoDB utilizan camel case. Para tener en cuenta esta diferencia, se puede usar el siguiente código para registrar un ConventionPack cuando la aplicación se inicie:

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

La siguiente clase modela documentos ImdbData:

public class ImdbData
{
public string Id { get; set; }
public int Votes { get; set; }
public float Rating { get; set; }
}

Para usar el controlador MongoDB.NET/C# para agregar una $replaceRoot etapa a una canalización de agregación, llame a ReplaceRoot()método en un PipelineDefinition objeto.

El siguiente ejemplo crea una etapa del pipeline que reemplaza cada documento Movie de entrada con el documento ImdbData almacenado en su propiedad Imdb:

var pipeline = new EmptyPipelineDefinition<Movie>()
.ReplaceRoot(m => m.ImdbData);

Los ejemplos de Node.js en esta página utilizan la base de datos sample_mflix de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulte Primeros pasos en la documentación del controlador de MongoDB Node.js.

Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $replaceRoot a una canalización de agregación, utilice el Operador $replaceRoot en un objeto de canalización.

El siguiente ejemplo crea una etapa de pipeline que reemplaza cada documento de entrada movie con el documento almacenado en su propiedad imdb. A continuación, el ejemplo ejecuta el pipeline de agregación:

const pipeline = [{ $replaceRoot: { newRoot: "$imdb" } }];
const cursor = collection.aggregate(pipeline);
return cursor;

Para aprender más sobre las etapas relacionadas de la pipeline, consulta la guía $replaceRoot.

Volver

Utilizar una restricción a nivel de campo

En esta página