Learn the "why" behind slow queries and how to fix them in our 2-Part Webinar.
Register now >
Docs Menu
Docs Home
/ /

$map (expression operator)

$map

Applies an expression to each item in an array and returns an array with the applied results.

You can use $map for deployments hosted in the following environments:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud

The $map expression has the following syntax:

{
$map: {
input: <expression>,
as: <string>,
arrayIndexAs: <string>,
in: <expression>
}
}
Field
Specification

input

An expression that resolves to an array.

If input resolves to null or refers to a missing field, $map returns null.

If input resolves to a non-array, non-null value, the pipeline errors.

as

Optional. A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this.

arrayIndexAs

Optional. A name for the aggregation variable that represents the index of the current element in the input array. The first array element index is 0.

You can use the variable name in an expression. For example, if you specify arrayIndexAs: "myIndex", you use $$myIndex in the expression. $$myIndex returns the index of the current element in the input array.

If you omit arrayIndexAs, you can use the $$IDX system variable in the expression to return the index of the current element.

For examples, see Access the Index of Each Item in an Array and Use $$IDX to Access the Index.

New in version 8.3.

in

An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as.

For more information on expressions, see Expressions.

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 ]
}
]

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 ]
}
]

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 ]
}
]

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 rank field.

  • isPrimary boolean that is true for the first hobby in the list, and false for 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 }
]

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 ] }
}
}
}
}
}
] )

To learn more about expressions used in the previous examples, see:

Back

$ltrim

On this page