Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

123
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!