Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

122
Vistas
Encapsulate/Transform an Array into an Array of Objects

I am currently in the process of modifying a schema and I need to do a relatively trivial transform using the aggregation framework and a bulkWrite.

I want to be able to take this array:

{ 
     ...,
     "images" : [
        "http://example.com/...", 
        "http://example.com/...", 
        "http://example.com/..."
    ] 
}

and aggregate to a similar array where the original value is encapsulated:

{ 
     ...,
     "images" : [
        {url: "http://example.com/..."}, 
        {url: "http://example.com/..."}, 
        {url: "http://example.com/..."}
    ] 
}

This slow query works, but it is ridiculously expensive to unwind an entire collection.

[
    {
        $match: {}
    },
    {
        $unwind: {
            path : "$images",
        }
    },
    {
        $group: {
            _id: "$_id",
            images_2: {$addToSet: {url: "$images"}}
        }
    },
]

How can this be achieved with project or some other cheaper aggregation?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

$map expression should do the job, try this:

db.col.aggregate([
  {
    $project: {
      images: {
        $map: {
          input: '$images',
          as: 'url',
          in: {
            url: '$$url'
          }
        }
      }
    }
  }
]);
over 4 years ago · Santiago Trujillo Denunciar

0

You don't need to use the bulkWrite() method for this.

You can use the $map aggregation array operator to apply an expression to each element element in your array.

Here, the expression simply create a new object where the value is the item in the array.

let mapExpr = {
    "$map": {
        "input": "$images",
        "as": "imageUrl",
        "in": { "url": "$$imageUrl }
    }
};

Finally you can use the $out aggregation pipeline operator to overwrite your collection or write the result into a different collection.

Of course $map is not an aggregation pipeline operator so which means that the $map expression must be use in a pipeline stage.

The way you do this depends on your MongoDB version.

The best way is in MongoDB 3.4 using $addFields to change the value of the "images" field in your document.

db.collection.aggregate([
    { "$addFields": { "images": mapExpr }},
    { "$out": "collection }
])

From MongoDB 3.2 backwards, you need to use the $project pipeline stage but you also need to include all the other fields manually in your document

db.collection.aggregate([
    { "$project": { "images": mapExpr } },
    { "$out": "collection }
])
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda