Actualmente estoy en el proceso de modificar un esquema y necesito hacer una transformación relativamente trivial usando el marco de agregación y un bulkWrite .
Quiero poder tomar esta matriz:
{ ..., "images" : [ "http://example.com/...", "http://example.com/...", "http://example.com/..." ] }y agregar a una matriz similar donde se encapsula el valor original :
{ ..., "images" : [ {url: "http://example.com/..."}, {url: "http://example.com/..."}, {url: "http://example.com/..."} ] }Esta consulta lenta funciona, pero es ridículamente costoso deshacer una colección completa.
[ { $match: {} }, { $unwind: { path : "$images", } }, { $group: { _id: "$_id", images_2: {$addToSet: {url: "$images"}} } }, ] ¿Cómo se puede lograr esto con el project o alguna otra agregación más barata?
No necesita usar el método bulkWrite() para esto.
Puede usar el operador de matriz de agregación $map para aplicar una expresión a cada elemento de su matriz.
Aquí, la expresión simplemente crea un nuevo objeto donde el valor es el elemento de la matriz.
let mapExpr = { "$map": { "input": "$images", "as": "imageUrl", "in": { "url": "$$imageUrl } } }; Finalmente, puede usar el operador de tubería de agregación $out para sobrescribir su colección o escribir el resultado en una colección diferente.
Por supuesto, $map no es un operador de tubería de agregación, lo que significa que la expresión $map debe usarse en una etapa de tubería.
La forma de hacer esto depende de su versión de MongoDB.
La mejor manera es en MongoDB 3.4 usando $addFields para cambiar el valor del campo "imágenes" en su documento.
db.collection.aggregate([ { "$addFields": { "images": mapExpr }}, { "$out": "collection } ]) Desde MongoDB 3.2 hacia atrás, debe usar la etapa de canalización $project pero también debe incluir todos los demás campos manualmente en su documento
db.collection.aggregate([ { "$project": { "images": mapExpr } }, { "$out": "collection } ])