Definition
$mapApplies an expression to each item in an array and returns an array with the applied results.
Compatibility
You can use $map for deployments hosted in the following
environments:
MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: The subscription-based, self-managed version of MongoDB
MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB
Syntax
The $map expression has the following syntax:
{ $map: { input: <expression>, as: <string>, arrayIndexAs: <string>, in: <expression> } }
Field | Specification |
|---|---|
| An expression that resolves to an array. If If |
| Optional. A name for the variable that represents each
individual element of the |
| Optional. A name for the aggregation variable that represents the index of the current
element in the You can use the variable name in an expression. For example, if you
specify If you omit For examples, see Access the Index of Each Item in an Array and
Use New in version 8.3. |
| An expression that is
applied to each element of the |
For more information on expressions, see Expressions.
Examples
Add to Each Element of an Array
In mongosh, create a sample collection named
grades with the following documents:
db.grades.insertMany( [ { quizzes: [ 5, 6, 7 ] }, { quizzes: [ ] }, { quizzes: [ 3, 8, 9 ] } ] )
The following aggregation operation uses $map with the
$add expression to increment each element in the
quizzes array by 2.
db.grades.aggregate( [ { $project: { adjustedGrades: { $map: { input: "$quizzes", as: "grade", in: { $add: [ "$$grade", 2 ] } } } } } ] )
This operation returns the following results:
[ { _id: ObjectId("6390b8f7237da390c6869a62"), adjustedGrades: [ 7, 8, 9 ] }, { _id: ObjectId("6390b8f7237da390c6869a63"), adjustedGrades: [] }, { _id: ObjectId("6390b8f7237da390c6869a64"), adjustedGrades: [ 5, 10, 11 ] } ]
Truncate Each Array Element
In mongosh, create a sample collection named
deliveries with the following documents:
db.deliveries.insertMany( [ { "city" : "Bakersfield", "distances" : [ 34.57, 81.96, 44.24 ] }, { "city" : "Barstow", "distances" : [ 73.28, 9.67, 124.36 ] }, { "city" : "San Bernadino", "distances" : [ 16.04, 3.25, 6.82 ] } ] )
The following aggregation operation uses $map to
truncate each element in the distances array
to its integer.
db.deliveries.aggregate( [ { $project: { city: "$city", integerValues: { $map: { input: "$distances", as: "decimalValue", in: { $trunc: "$$decimalValue" } } } } } ] )
This operation returns the following results:
[ { _id: ObjectId("6390b9b1237da390c6869a65"), city: 'Bakersfield', integerValues: [ 34, 81, 44 ] }, { _id: ObjectId("6390b9b1237da390c6869a66"), city: 'Barstow', integerValues: [ 73, 9, 124 ] }, { _id: ObjectId("6390b9b1237da390c6869a67"), city: 'San Bernadino', integerValues: [ 16, 3, 6 ] } ]
Convert Celsius Temperatures to Fahrenheit
In mongosh, create a sample collection named
temperatures with the following documents:
db.temperatures.insertMany( [ { "date" : ISODate("2019-06-23"), "tempsC" : [ 4, 12, 17 ] }, { "date" : ISODate("2019-07-07"), "tempsC" : [ 14, 24, 11 ] }, { "date" : ISODate("2019-10-30"), "tempsC" : [ 18, 6, 8 ] } ] )
The following aggregation operation uses the $addFields
stage to add a new field to the documents called tempsF which
contains Fahrenheit equivalents of the elements in the tempsC
array. To convert from Celsius to Fahrenheit, the operation uses
$map to $multiply the Celsius
values by 9/5 and then $add 32.
db.temperatures.aggregate( [ { $addFields: { "tempsF": { $map: { input: "$tempsC", as: "tempInCelsius", in: { $add: [ { $multiply: [ "$$tempInCelsius", 9/5 ] }, 32 ] } } } } } ] )
This operation returns the following results:
[ { _id: ObjectId("6390ba11237da390c6869a68"), date: ISODate("2019-06-23T00:00:00.000Z"), tempsC: [ 4, 12, 17 ], tempsF: [ 39.2, 53.6, 62.6 ] }, { _id: ObjectId("6390ba11237da390c6869a69"), date: ISODate("2019-07-07T00:00:00.000Z"), tempsC: [ 14, 24, 11 ], tempsF: [ 57.2, 75.2, 51.8 ] }, { _id: ObjectId("6390ba11237da390c6869a6a"), date: ISODate("2019-10-30T00:00:00.000Z"), tempsC: [ 18, 6, 8 ], tempsF: [ 64.4, 42.8, 46.4 ] } ]
Access the Index of Each Item in an Array
Create a sample collection named people with these documents:
db.people.insertMany( [ { _id: 1, name: "Melissa", hobbies: [ "softball", "drawing", "reading" ] }, { _id: 2, name: "Brad", hobbies: [ "gaming", "skateboarding" ] }, { _id: 3, name: "Scott", hobbies: [ "basketball", "music", "fishing" ] }, { _id: 4, name: "Tracey", hobbies: [ "acting", "yoga" ] }, { _id: 5, name: "Josh", hobbies: [ "programming" ] }, { _id: 6, name: "Claire" } ] )
The hobbies field contains an array of each person's hobbies in
ranked order. The first hobby in the array is the person's primary hobby
that the person spends the most time on. The first hobby has an array
index of 0.
The following example uses arrayIndexAs. The myIndex variable
has the index of each hobby in the hobbies array. The example
returns documents with these fields:
Person name.
Hobby name.
Position of the hobby in the list of hobbies in the
rankfield.isPrimaryboolean that istruefor the first hobby in the list, andfalsefor the other hobbies.
db.people.aggregate( [ { $project: { _id: 0, name: 1, rankedHobbies: { $map: { input: "$hobbies", as: "hobby", arrayIndexAs: "myIndex", in: { hobby: "$$hobby", rank: { $add: [ "$$myIndex", 1 ] }, isPrimary: { $eq: [ "$$myIndex", 0 ] } } } } } } ] )
Output:
[ { name: 'Melissa', rankedHobbies: [ { hobby: 'softball', rank: 1, isPrimary: true }, { hobby: 'drawing', rank: 2, isPrimary: false }, { hobby: 'reading', rank: 3, isPrimary: false } ] }, { name: 'Brad', rankedHobbies: [ { hobby: 'gaming', rank: 1, isPrimary: true }, { hobby: 'skateboarding', rank: 2, isPrimary: false } ] }, { name: 'Scott', rankedHobbies: [ { hobby: 'basketball', rank: 1, isPrimary: true }, { hobby: 'music', rank: 2, isPrimary: false }, { hobby: 'fishing', rank: 3, isPrimary: false } ] }, { name: 'Tracey', rankedHobbies: [ { hobby: 'acting', rank: 1, isPrimary: true }, { hobby: 'yoga', rank: 2, isPrimary: false } ] }, { name: 'Josh', rankedHobbies: [ { hobby: 'programming', rank: 1, isPrimary: true } ] }, { name: 'Claire', rankedHobbies: null } ]
Use $$IDX to Access the Index
The $$IDX variable returns the index of the current
element in the input array. You can use $$IDX if you omit the
arrayIndexAs field from the expression.
The following example returns the same documents as the previous example
in Access the Index of Each Item in an Array, but uses $$IDX instead of
arrayIndexAs:
db.people.aggregate( [ { $project: { _id: 0, name: 1, rankedHobbies: { $map: { input: "$hobbies", as: "hobby", in: { hobby: "$$hobby", rank: { $add: [ "$$IDX", 1 ] }, isPrimary: { $eq: [ "$$IDX", 0 ] } } } } } } ] )
Learn More
To learn more about expressions used in the previous examples, see: