MongoDB $reduce Operator

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 4 Examples
Arrays

What You’ll Learn

The $reduce operator folds an array into a single value by processing each element with an accumulator. Use it to sum scores, find a maximum, concatenate strings, or build any custom aggregation over an array field.

01

Array Fold

Array → one value.

02

Syntax

input + initialValue + in.

03

$$value

Running accumulator.

04

$$this

Current element.

05

Use Cases

Sum, max, concat.

06

vs $map

Fold vs transform.

Definition and Usage

In MongoDB’s aggregation framework, the $reduce operator walks through an array element by element, updating an accumulator at each step. You provide the source array (input), a starting value (initialValue), and an expression (in) that combines the accumulator with the current element.

For example, summing [10, 20, 30] with initialValue: 0 produces 60. Unlike $map, which returns a new array, $reduce returns one final result per document.

💡
Beginner Tip

Think of $reduce as MongoDB’s version of Array.reduce(). Inside in, $$value is the running total so far and $$this is the current array item. Both use the double-dollar prefix.

📝 Syntax

The $reduce operator takes an object with input, initialValue, and in:

mongosh
{
  $reduce: {
    input: <array expression>,
    initialValue: <expression>,
    in: <expression>
  }
}

Variables Inside in

mongosh
// Sum numbers
{ $add: [ "$$value", "$$this" ] }

// Find maximum
{ $max: [ "$$value", "$$this" ] }

// Concatenate strings
{ $concat: [ "$$value", ", ", "$$this" ] }

// Sum qty * price from object elements
{ $add: [
    "$$value",
    { $multiply: [ "$$this.qty", "$$this.price" ] }
]}

Syntax Rules

  • input — the array to fold (field path like "$scores" or a literal array).
  • initialValue — starting accumulator (e.g. 0 for sum, "" for concat).
  • in — expression that returns the new accumulator each step.
  • $$value — current accumulator; $$this — current element.
  • Empty array returns initialValue without running in.
  • If input is null or missing, $reduce returns null.
  • Use inside $project, $addFields, or $set.

💡 $reduce vs $map vs $sum

$reduce → folds array into one value (sum, max, custom logic)
$map → transforms each element; output is a new array
$sum in $group → aggregates across documents, not within one array field
Analogy$reduce = array.reduce(), $map = array.map()

⚡ Quick Reference

QuestionAnswer
Operator typeAggregation array expression operator
Syntax{ $reduce: { input, initialValue, in } }
Accumulator$$value
Current element$$this
Empty arrayReturns initialValue
Sum
{
  $reduce: {
    input: "$scores",
    initialValue: 0,
    in: {
      $add: ["$$value","$$this"]
    }
  }
}

Total of scores

Max
{
  $reduce: {
    input: "$scores",
    initialValue: null,
    in: {
      $max: ["$$value","$$this"]
    }
  }
}

Highest score

Concat
{
  $reduce: {
    input: "$tags",
    initialValue: "",
    in: {
      $concat: ["$$value","$$this"]
    }
  }
}

Join strings

Empty []
initialValue: 0
// input: [] → 0

Returns initial

Examples Gallery

Sum student scores, total order line items, find the maximum value, and concatenate tag strings with $reduce.

📚 Sum an Array of Numbers

Fold a scores array into a single total with $project.

Sample Input Documents

Suppose you have a students collection:

mongosh
[
  {
    "_id": 1,
    "name": "Alice",
    "scores": [70, 85, 90]
  },
  {
    "_id": 2,
    "name": "Bob",
    "scores": [60, 75, 80]
  }
]

Example 1 — Sum Scores with $reduce

Add all values in the scores array:

mongosh
db.students.aggregate([
  {
    $project: {
      name: 1,
      totalScore: {
        $reduce: {
          input: "$scores",
          initialValue: 0,
          in: { $add: [ "$$value", "$$this" ] }
        }
      }
    }
  }
])

How It Works

  • Step 1: 0 + 70 = 70
  • Step 2: 70 + 85 = 155
  • Step 3: 155 + 90 = 245 (final result for Alice)

📈 Practical Patterns

Order totals from object arrays, maximum values, and string concatenation.

Example 2 — Order Total from Line Items

Sum qty × price across an array of item objects:

mongosh
db.orders.aggregate([
  {
    $project: {
      orderId: 1,
      orderTotal: {
        $reduce: {
          input: "$items",
          initialValue: 0,
          in: {
            $add: [
              "$$value",
              { $multiply: [ "$$this.qty", "$$this.price" ] }
            ]
          }
        }
      }
    }
  }
])

// items: [{ qty: 2, price: 10 }, { qty: 1, price: 25 }]
// orderTotal: 45

How It Works

When array elements are objects, access fields on $$this: $$this.qty and $$this.price. Each step adds the line total to the running sum.

Example 3 — Find the Maximum Score

Use $max inside in to track the highest value:

mongosh
db.students.aggregate([
  {
    $project: {
      name: 1,
      topScore: {
        $reduce: {
          input: "$scores",
          initialValue: null,
          in: { $max: [ "$$value", "$$this" ] }
        }
      }
    }
  }
])

How It Works

Starting with null, $max compares the accumulator with each element. The final $$value is the largest number in the array.

Example 4 — Concatenate Tags

Join an array of strings into one comma-separated label:

mongosh
db.products.aggregate([
  {
    $project: {
      name: 1,
      tagLabel: {
        $reduce: {
          input: "$tags",
          initialValue: "",
          in: {
            $cond: [
              { $eq: [ "$$value", "" ] },
              "$$this",
              { $concat: [ "$$value", ", ", "$$this" ] }
            ]
          }
        }
      }
    }
  }
])

// tags: ["sale", "new", "featured"]
// tagLabel: "sale, new, featured"

How It Works

The $cond avoids a leading comma on the first element. For the first tag, output just $$this; afterward, prepend ", ".

Bonus — $reduce with $range

Compute the sum of 1 through 5 using a generated sequence:

mongosh
db.samples.aggregate([
  {
    $project: {
      sumOneToFive: {
        $reduce: {
          input: { $range: [1, 6] },
          initialValue: 0,
          in: { $add: [ "$$value", "$$this" ] }
        }
      }
    }
  }
])

// sumOneToFive: 15  (1+2+3+4+5)

How It Works

$range creates [1, 2, 3, 4, 5]; $reduce folds it into a single sum. Pair sequence generators with $reduce for indexed calculations.

🚀 Use Cases

  • Array totals — sum numeric fields stored as arrays (scores, quantities).
  • Order calculations — compute line-item totals from embedded items arrays.
  • Min / max — find extremes with $min or $max in in.
  • String building — concatenate tags, names, or labels into one display field.

🧠 How $reduce Works

1

Accumulator starts at initialValue

MongoDB sets $$value to initialValue before processing the first element.

Start
2

Each element updates $$value

For every item, $$this is the current element and in returns the new accumulator.

Loop
3

Final $$value is returned

After the last element, the accumulator becomes the single output value stored in your projected field.

Result
=

One value from many

Arrays collapse into totals, extremes, or custom aggregates per document.

Conclusion

The $reduce operator folds arrays into single values in MongoDB aggregation pipelines. With input, initialValue, and in, you can sum, find maxima, concatenate strings, or implement any custom fold logic over embedded arrays.

Remember $$value is the accumulator and $$this is the current element. Empty arrays return initialValue. Next in the series: $regex.

💡 Best Practices

✅ Do

  • Pick initialValue that matches your goal (0 for sum, "" for concat)
  • Use $$value and $$this inside in
  • Handle object arrays with $$this.fieldName
  • Pair with $range for sequence-based folds
  • Consider $sum in $group when aggregating across documents

❌ Don’t

  • Confuse $$value with single-$ field paths
  • Use $reduce when $map needs an array output
  • Forget empty arrays return initialValue
  • Skip initialValue (it is required)
  • Assume null input behaves like an empty array (it returns null)

Key Takeaways

Knowledge Unlocked

Five things to remember about $reduce

Use these points when folding arrays in aggregation pipelines.

5
Core concepts
📝 02

Three Parts

input, initial, in.

Syntax
🛠 03

$$value / $$this

Acc + current.

Variables
💰 04

Sum & Max

Common folds.

Use case
05

Empty Array

Returns initial.

Edge case

❓ Frequently Asked Questions

$reduce folds an array into a single value by applying an expression to each element while carrying an accumulator. It is like JavaScript's Array.reduce() inside an aggregation expression.
The syntax is { $reduce: { input: <array>, initialValue: <expression>, in: <expression> } }. Inside in, use $$value for the accumulator and $$this for the current element.
Use $$value for the running result and $$this for the current array element inside the in expression. Both require the double-dollar prefix.
$reduce returns initialValue when the input array is empty. No elements are processed and the accumulator stays at its starting value.
$map transforms every element and returns a new array of the same length. $reduce processes elements sequentially and returns one final value (sum, max, concatenated string, etc.).

Continue the Operator Series

Move on to $regex for pattern matching, or review $map for element-wise transforms.

Next: $regex →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful