MongoDB map array of objects

Examples

Return a new array with the square root of all element values:

const numbers = [4, 9, 16, 25];
const newArr = numbers.map(Math.sqrt)

Try it Yourself »

Multiply all the values in an array with 10:

const numbers = [65, 44, 12, 4];
const newArr = numbers.map(myFunction)

function myFunction(num) {
  return num * 10;
}

Try it Yourself »

More examples below.


Definition and Usage

map() creates a new array from calling a function for every array element.

map() calls a function once for each element in an array.

map() does not execute the function for empty elements.

map() does not change the original array.


Syntax

array.map(function(currentValue, index, arr), thisValue)

Parameters

ParameterDescriptionfunction()Required.
A function to be run for each array element.currentValueRequired.
The value of the current element.indexOptional.
The index of the current element.arrOptional.
The array of the current element.thisValueOptional.
Default value undefined.
A value passed to the function to be used as its this value.

Return Value

TypeDescriptionAn arrayThe results of a function for each array element.

More Examples

Get the full name for each person:

const persons = [
  {firstname : "Malcom", lastname: "Reynolds"},
  {firstname : "Kaylee", lastname: "Frye"},
  {firstname : "Jayne", lastname: "Cobb"}
];

persons.map(getFullName);

function getFullName(item) {
  return [item.firstname,item.lastname].join(" ");
}

Try it Yourself »


Browser Support

map() is an ECMAScript5 (ES5) feature.

ES5 (JavaScript 2009) fully supported in all browsers:

ChromeEdgeFirefoxSafariOperaIEYesYesYesYesYes9-11

Question: I'm new on mongodb. so I try design the schema, and the problem I don't know how to do a query on mongodb, so the output, Question: Lets say I have a MongoDB collection with docs, a nested prop in mongodb to see if any of those ids exsist., The DB looks like this. alertDetails is an array and it contains objects, these objects

Thomas Beale 2022-08-18

Solution 1: Since you have nested arrays,, ": "_id", "as": "productObjects" }}, // Unwind the result arrays ( likely one or none, { var scope = this; logger.info(this.TAG, "Read operation execution started on ORM Object, : "$clg.members.student" } } ], Now with the second unwind each object, $mergeObjects to merge both the collection objects

Sharon Smith 2022-11-20

$push: {value: '$names.value', changed_at: '$names.changed_at'}}}}, {$limit: 3}, { $lookup, When I remove either $lookup or $group it works and gives the expected result., > stack JavaScript apps with the MEAN stack, using Node.js, AngularJS, Express and MongoDB, title="Get started with the Hotel API"> api / hotels /, my database returns an empty array, I send a request using postman on the route upon which this function is called, it returns an empty array

score:2

Accepted answer

You need to use double dollar sign to refer to a variable, working example:

{
    $replaceRoot: {
        newRoot: {
            $mergeObjects: [
                { _id: "$_id", name: "$name" },
                {
                    $arrayToObject: {
                        $map: {
                            input: { $objectToArray: "$attribute_bag" },
                            in: [ "$$this.k", "$$this.v.value" ]
                        }
                    }
                }
            ]
        }
    }
}

Mongo Playground

More questions with similar tag


If you work with javascript, the chances of you are using array methods like map, filter and reducer today are really great.

All simplicity offered by javascript higher-order functions makes our code more readable and concise, mainly when we work with array data transformations.

Let's remember these methods:

const numbers = [2, 8, 15];

const greaterThanFive = (num) => num > 5;
const multiplyBy2 = (num) => num * 2;
const sum = (acc, num) => acc + num;

const filtered = numbers.filter(greaterThanFive);
const mapped = numbers.map(multiplyBy2);
const reduced = numbers.reduce(sum);

console.log(filtered); // [8, 15]
console.log(mapped); // [4, 16, 30]
console.log(reduced); // 25

Enter fullscreen mode Exit fullscreen mode

That's really amazing!

However, in databases scenario, querying data with this simplicity is usually unusual, unless that database is MongoDB.

Because MongoDB is a NoSQL database with JSON based model, some javascript array methods have similar
in MongoDB Aggregation Pipeline.

About its JSON nature, official website cites:

MongoDB’s document data model naturally supports JSON and its expressive query language is simple for developers to learn and use.

And that makes all difference folks...

Let's get

[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]
2 array data used in the javascript example to create a new document in a generic collection. For improve the understanding, I will use MongoDB Playground to test our queries:

[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

Good! Our collection is ready to receive queries now :)

$filter

Starting, let's use $filter aggregation pipeline operator.

Query

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      filtered: {
        $filter: {
          input: "$numbers",
          as: "num",
          cond: {
            $gt: [
              "$$num",
              5
            ]
          }
        }
      }
    }
  }
])

Enter fullscreen mode Exit fullscreen mode

  • Start using
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    3 method to submit the query. That method enables aggregation framework;
  • Pipeline starts using
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    4 aggregation pipeline stage. The specified fields inside it can be existing fields from the input documents or newly computed fields. In our case,
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    5 field will be created and added to response;
  • The computed value for
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    5 field will be given by
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    7 aggregation pipeline operator;
  • Inside filter operator, set input to
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    8. That's our array to be iterated;
  • Set as to
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    9 to get each array value to test in filter condition. You could use any name here, just like you did in javascript filter method;
  • Then, set the filter condition in
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    0 using
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    1 expression to return a boolean if current array value
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    2 is greater than 5;

Response

[
  {
    "filtered": [
      8,
      15
    ]
  }
]

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

$map

$map operator is pretty similar to

[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]
7, however while
[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]
7 needs a condition,
db.collection.aggregate([
  {
    $project: {
      _id: 0,
      filtered: {
        $filter: {
          input: "$numbers",
          as: "num",
          cond: {
            $gt: [
              "$$num",
              5
            ]
          }
        }
      }
    }
  }
])
5 you must set
db.collection.aggregate([
  {
    $project: {
      _id: 0,
      filtered: {
        $filter: {
          input: "$numbers",
          as: "num",
          cond: {
            $gt: [
              "$$num",
              5
            ]
          }
        }
      }
    }
  }
])
6 to output a new array value according to some rule.

Query

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      mapped: {
        $map: {
          input: "$numbers",
          as: "num",
          in: {
            $multiply: [
              "$$num",
              2
            ]
          }
        }
      }
    }
  }
])

Enter fullscreen mode Exit fullscreen mode

In case, using

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      filtered: {
        $filter: {
          input: "$numbers",
          as: "num",
          cond: {
            $gt: [
              "$$num",
              5
            ]
          }
        }
      }
    }
  }
])
7 expression to return all array values multiplied by 2.

Response

[
  {
    "mapped": [
      4,
      16,
      30
    ]
  }
]

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

$reduce

$reduce operator applies an expression to each element in an array and combines them into a single value.

Query

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      reduced: {
        $reduce: {
          input: "$numbers",
          initialValue: 0,
          in: {
            $sum: [
              "$$value",
              "$$this"
            ]
          }
        }
      }
    }
  }
])

Enter fullscreen mode Exit fullscreen mode

  • Again, set
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    8 array as
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    9 to iterate;
  • The initial cumulative value set before
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    6 is applied to the first element of the input array,
    [
      {
        "filtered": [
          8,
          15
        ]
      }
    ]
    
    1 is set to 0;
  • Finally,
    db.collection.aggregate([
      {
        $project: {
          _id: 0,
          filtered: {
            $filter: {
              input: "$numbers",
              as: "num",
              cond: {
                $gt: [
                  "$$num",
                  5
                ]
              }
            }
          }
        }
      }
    ])
    
    6 expression give us two special variables:
    [
      {
        "filtered": [
          8,
          15
        ]
      }
    ]
    
    3 is the variable that represents the cumulative value of the expression (
    [
      {
        "filtered": [
          8,
          15
        ]
      }
    ]
    
    4 in javascript example) and
    [
      {
        "filtered": [
          8,
          15
        ]
      }
    ]
    
    5 is the variable that refers to the element being processed (
    [
      {
        "numbers": [
          2,
          8,
          15
        ]
      },
    ]
    
    9 in javascript example). In case, using
    [
      {
        "filtered": [
          8,
          15
        ]
      }
    ]
    
    7 expression to return the new accumulated value.

Response

[
  {
    "reduced": 25
  }
]

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

All in one

In previous examples, we worked with each operator in a separated query, however we could do a single query requesting all operators at once.

Query

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      filtered: {
        $filter: {
          input: "$numbers",
          as: "num",
          cond: {
            $gte: [
              "$$num",
              5
            ]
          },

        }
      },
      mapped: {
        $map: {
          input: "$numbers",
          as: "num",
          in: {
            $multiply: [
              "$$num",
              2
            ]
          }
        }
      },
      reduced: {
        $reduce: {
          input: "$numbers",
          initialValue: 0,
          in: {
            $sum: [
              "$$value",
              "$$this"
            ]
          }
        }
      }
    }
  }
])

Enter fullscreen mode Exit fullscreen mode

Response

[
  {
    "filtered": [
      8,
      15
    ],
    "mapped": [
      4,
      16,
      30
    ],
    "reduced": 25
  }
]

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

Going further, if you add more documents to collection, this same query computes data for each of them. Let's query a collection with 3 documents now:

Collection

[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]
0

Enter fullscreen mode Exit fullscreen mode

Response

[
  {
    "numbers": [
      2,
      8,
      15
    ]
  },
]
1

Enter fullscreen mode Exit fullscreen mode

Mongo Playground

Conclusion

MongoDB for javascript developers is intuitive by nature! Aggregation framework does the hard work directly in the database server using many of features already known by us and data can be delivered ready-to-use, which normally decreases the workload for the application server.