Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

$replaceWith (etapa de agregación)

$replaceWith

Sustituye el documento de entrada por el documento especificado. Esta operación reemplaza todos los campos existentes en el documento de entrada, incluido el campo _id. Con $replaceWith, puede elevar un documento incrustado al nivel superior. También puede especificar un nuevo documento como reemplazo.

La etapa $replaceWith realiza la misma acción que la etapa $replaceRoot, pero las etapas tienen formas diferentes.

La etapa $replaceWith tiene la siguiente forma:

{ $replaceWith: <replacementDocument> }

El documento de reemplazo puede ser cualquier expresión válida que se resuelva en un documento. Para obtener más información sobre las expresiones, consulta Expresiones.

Si <replacementDocument> no es un documento, $replaceWith genera un error y falla.

Si <replacementDocument> se resuelve en un documento inexistente (es decir, el documento no existe), $replaceWith genera un error y falla. Por ejemplo, cree 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 operación $replaceWith falla porque uno de los documentos no tiene el campo name:

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

Para evitar el error, puedes usar $mergeObjects para combinar el documento name con un documento por defecto; por ejemplo:

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

Como alternativa, puede omitir los documentos a los que les falta el campo name incluyendo una etapa $match para comprobar la existencia del campo del documento antes de pasar los documentos a la etapa $replaceWith:

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

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

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

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

db.people.insertMany([
{ "_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 $replaceWith para reemplazar cada documento de entrada con el resultado de una operación $mergeObjects. La expresión $mergeObjects combina el documento predeterminado especificado con el documento pets.

db.people.aggregate( [
{ $replaceWith: { $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 } } },
{ $replaceWith: "$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 }
]

Una colección de ejemplo sales se rellena con los siguientes documentos:

db.sales.insertMany([
{ "_id" : 1, "item" : "butter", "price" : 10, "quantity": 2, date: ISODate("2019-03-01T08:00:00Z"), status: "C" },
{ "_id" : 2, "item" : "cream", "price" : 20, "quantity": 1, date: ISODate("2019-03-01T09:00:00Z"), status: "A" },
{ "_id" : 3, "item" : "jam", "price" : 5, "quantity": 10, date: ISODate("2019-03-15T09:00:00Z"), status: "C" },
{ "_id" : 4, "item" : "muffins", "price" : 5, "quantity": 10, date: ISODate("2019-03-15T09:00:00Z"), status: "C" }
])

Supongamos que, para fines de generación de informes, desea calcular el importe total de cada venta completada hasta el momento de la ejecución del informe. La siguiente operación busca todas las ventas con estado C y crea nuevos documentos mediante la etapa $replaceWith. La etapa $replaceWith calcula el importe total y utiliza la variable NOW para obtener la hora actual.

db.sales.aggregate([
{ $match: { status: "C" } },
{ $replaceWith: { _id: "$_id", item: "$item", amount: { $multiply: [ "$price", "$quantity"]}, status: "Complete", asofDate: "$$NOW" } }
])

La operación devuelve los siguientes documentos:

[
{ _id: 1, item: 'butter', amount: 20, status: 'Complete', asofDate: '...' },
{ _id: 3, item: 'jam', amount: 50, status: 'Complete', asofDate: '...' },
{ _id: 4, item: 'muffins', amount: 50, status: 'Complete', asofDate: '...' }
]

Una colección de ejemplo reportedsales se completa con la información de ventas reportada por trimestre y región:

db.reportedsales.insertMany( [
{ _id: 1, quarter: "2019Q1", region: "A", qty: 400 },
{ _id: 2, quarter: "2019Q1", region: "B", qty: 550 },
{ _id: 3, quarter: "2019Q1", region: "C", qty: 1000 },
{ _id: 4, quarter: "2019Q2", region: "A", qty: 660 },
{ _id: 5, quarter: "2019Q2", region: "B", qty: 500 },
{ _id: 6, quarter: "2019Q2", region: "C", qty: 1200 }
] )

Supón que para fines de reporte, deseas ver los datos de ventas reportados por trimestre; por ejemplo.

{ "_id" : "2019Q1", "A" : 400, "B" : 550, "C" : 1000 }

Para ver los datos agrupados por trimestre, puedes usar la siguiente pipeline de agregación:

db.reportedsales.aggregate( [
{ $addFields: { obj: { k: "$region", v: "$qty" } } },
{ $group: { _id: "$quarter", items: { $push: "$obj" } } },
{ $project: { items2: { $concatArrays: [ [ { "k": "_id", "v": "$_id" } ], "$items" ] } } },
{ $replaceWith: { $arrayToObject: "$items2" } }
] )
Primera etapa:

La etapa $addFields añade un nuevo campo de documento obj que define la clave k como el valor de la región y el valor v como la cantidad para esa región. Por ejemplo:

{ "_id" : 1, "quarter" : "2019Q1", "region" : "A", "qty" : 400, "obj" : { "k" : "A", "v" : 400 } }
Segunda fase:

La etapa $group agrupa por trimestre y utiliza $push para acumular los campos obj en un nuevo campo de arreglo items. Por ejemplo:

{ "_id" : "2019Q1", "items" : [ { "k" : "A", "v" : 400 }, { "k" : "B", "v" : 550 }, { "k" : "C", "v" : 1000 } ] }
Tercera etapa:

La etapa $project utiliza $concatArrays para crear un nuevo arreglo items2 que incluye la información _id y los elementos del arreglo items:

{ "_id" : "2019Q1", "items2" : [ { "k" : "_id", "v" : "2019Q1" }, { "k" : "A", "v" : 400 }, { "k" : "B", "v" : 550 }, { "k" : "C", "v" : 1000 } ] }
Cuarta etapa:

El $replaceWith utiliza el $arrayToObject para convertir el items2 en un documento, utilizando los pares clave k y valor v especificados, y envía ese documento a la siguiente etapa. Por ejemplo:

{ "_id" : "2019Q1", "A" : 400, "B" : 550, "C" : 1000 }

La agregación devuelve el siguiente documento:

[
{ _id: '2019Q1', A: 400, B: 550, C: 1000 },
{ _id: '2019Q2', A: 660, B: 500, C: 1200 }
]

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", cell: "987-654-3210", email: "beo@example.net" }
] )

La siguiente operación utiliza $replaceWith con $mergeObjects para generar los documentos actuales con valores predeterminados para los campos faltantes:

db.contacts.aggregate( [
{ $replaceWith:
{ $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: '987-654-3210',
home: ''
}
]

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