Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

120
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda