Array Operators

Work with arrays — extract, combine, search, transform, and filter array elements.

Previous | Index | Next: 13 - Accumulator Operators


Array operators let you manipulate array fields within documents. These are some of the most powerful expressions in the aggregation framework.


$arrayElemAt — Access by Index

Extracts a single element from an array at a given index.

{ $arrayElemAt: [<array>, <index>] }
  • Index 0 is the first element.
  • Negative indices count from the end: -1 is the last element.

Example: Get the first funding source

db.projects.aggregate([
  {
    $project: {
      _id: 0,
      title: 1,
      funding: { $arrayElemAt: ["$fundings", 0] }
    }
  }
]);

$concatArrays — Merge Arrays

Combines elements from multiple arrays into a single array.

{ $concatArrays: [<array1>, <array2>, ...] }

Example

db.warehouse.insertMany([
  { instock: ["apples", "pudding", "pie"] },
  { instock: ["ice cream"], ordered: [] },
  { instock: ["chocolate"], ordered: ["butter", "apples"] }
]);
 
db.warehouse.aggregate([
  {
    $project: {
      items: { $concatArrays: ["$instock", "$ordered"] }
    }
  },
  { $out: "warehouseReport" }
]);

Output:

{ items: null }                                  // $ordered missing → null
{ items: ["ice cream"] }                         // empty ordered array
{ items: ["chocolate", "butter", "apples"] }     // both merged

Note: If any argument is null or missing, the entire result is null.


$in — Check Array Membership

Tests whether a value exists in an array. Returns true or false.

{ $in: [<value>, <array expression>] }

Example: Check if bananas are in stock

db.warehouse.insertMany([
  { in_stock: ["apples", "oranges"],  location: "24th Street" },
  { in_stock: ["bananas", "pears"],   location: "36th Street" },
  { in_stock: ["apples"],             location: "82nd Street" }
]);
 
db.warehouse.aggregate([
  {
    $project: {
      storeLocation: "$location",
      bananaInStock: { $in: ["bananas", "$in_stock"] }
    }
  },
  { $out: "warehouseReport" }
]);

Output:

{ storeLocation: "24th Street", bananaInStock: false }
{ storeLocation: "36th Street", bananaInStock: true }
{ storeLocation: "82nd Street", bananaInStock: false }

$map — Transform Each Element

Applies an expression to every element in an array — like Array.map() in JavaScript or a foreach loop.

{
  $map: {
    input: <array expression>,     // the source array
    as:    <variable name>,        // name for each element (default: "this")
    in:    <expression>            // what to compute for each element
  }
}

Use $$<varName> to reference the current element inside in.

Example: Add 2 to every value

db.results.insertMany([
  { _id: 1, values: [5, 6, 7] },
  { _id: 2, values: [] },
  { _id: 3, values: [3, 8, 9] }
]);
 
db.results.aggregate([
  {
    $project: {
      adjustedValues: {
        $map: {
          input: "$values",
          as: "value",
          in: { $add: ["$$value", 2] }
        }
      }
    }
  }
]);

Output:

{ _id: 1, adjustedValues: [7, 8, 9] }
{ _id: 2, adjustedValues: [] }
{ _id: 3, adjustedValues: [5, 10, 11] }

$filter — Keep Matching Elements

Filters an array, keeping only elements that match a condition — like Array.filter() in JavaScript.

{
  $filter: {
    input: <array>,             // source array
    as:    <variable name>,     // name for each element
    cond:  <boolean expression> // keep element if true
  }
}

Example: Remove management projects from a facility’s project list

db.facilities.aggregate([
  {
    $addFields: {
      projects: {
        $filter: {
          input: "$projects",
          as: "project",
          cond: {
            $ne: ["$$project.type", "MANAGEMENT_PROJECT"]
          }
        }
      }
    }
  },
  { $out: "facilityReport" }
]);

$reduce — Collapse to a Single Value

Iterates through an array and accumulates a single result — like Array.reduce() in JavaScript.

{
  $reduce: {
    input:        <array>,         // source array
    initialValue: <expression>,    // starting accumulator value
    in:           <expression>     // applied to each element
  }
}

Inside in, two special variables are available:

  • $$value — the current accumulator
  • $$this — the current array element

Example: Sum and product in one pass

{
  $reduce: {
    input: [1, 2, 3, 4],
    initialValue: { sum: 5, product: 2 },
    in: {
      sum:     { $add:      ["$$value.sum", "$$this"] },
      product: { $multiply: ["$$value.product", "$$this"] }
    }
  }
}
// → { sum: 15, product: 48 }
//   sum:     5+1+2+3+4 = 15
//   product: 2×1×2×3×4 = 48

Example: Concatenate strings

db.projects.aggregate([
  {
    $addFields: {
      value: {
        $reduce: {
          input: ["a", "b", "c"],
          initialValue: "",
          in: { $concat: ["$$value", "$$this"] }
        }
      }
    }
  }
]);
// → value: "abc"

$isArray — Type Check

Returns true if the expression evaluates to an array.

{ $isArray: <expression> }

Example: Safe default for non-array fields

db.projects.aggregate([
  {
    $addFields: {
      items: {
        $cond: [
          { $isArray: "$reviews" },
          [],       // if reviews is an array → empty array
          null      // if not → null
        ]
      }
    }
  },
  { $out: "projectReport" }
]);

Quick Reference

OperatorJS EquivalentPurpose
$arrayElemAtarr[i]Access element by index
$concatArrays[...a, ...b]Merge arrays
$inarr.includes(x)Check membership
$maparr.map(fn)Transform each element
$filterarr.filter(fn)Keep matching elements
$reducearr.reduce(fn, init)Collapse to single value
$isArrayArray.isArray(x)Type check

Next: 13 - Accumulator Operators