MongoDB $reduce Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $reduce?

$reduce is a MongoDB aggregation expression that folds an array into one value. It walks each element, updates an accumulator, and returns the final result—like JavaScript’s Array.reduce().

Remember
$reduce = fold array → one value

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

inside in:
  $$value → accumulator (so far)
  $$this  → current element

empty array → initialValue
null input  → null
UsePrefer
One result from an array$reduce
One result per element$map
Keep matching elements$filter

How to Use $reduce in MongoDB

Provide the array, a starting accumulator, and the update expression.

  1. Choose an expression stage ($addFields or $project).
  2. Set input to the array field (for example "$scores").
  3. Set initialValue (for a sum, start at 0).
  4. In in, combine $$value and $$this (for example with $add).
PieceRequired?Role
inputYesArray to walk
initialValueYesStarting accumulator
inYesHow to update using $$value + $$this

Pseudocode

Pseudocode
arr = evaluate(input)
if arr is null or missing:
    result = null
else:
    acc = evaluate(initialValue)
    for each element in arr:
        $$this  = element
        $$value = acc
        acc = evaluate(in)
    result = acc
emit { ..., field: result }

Cheat Sheet

Keep these facts handy while folding arrays in pipelines.

TopicDetail
TypeAggregation expression (returns one value)
Syntax{ $reduce: { input, initialValue, in } }
Variables$$value · $$this
vs $mapOne value vs new array
Empty arrayReturns initialValue
Null inputReturns null
Sample sum[10, 20, 30] → 60

Live Preview

Watch $reduce fold [10, 20, 30] into a sum, a max, or a joined string.

Simulates { $reduce: { input, initialValue, in } }.

Result
input = [10, 20, 30]
initialValue = 0

step 1: $$value=0  $$this=10 → 10
step 2: $$value=10 $$this=20 → 30
step 3: $$value=30 $$this=30 → 60

result → 60

Worked Walkthrough — Sum Scores

Asha has quiz scores 10, 20, 30. We start the accumulator at 0 and add each score with $reduce.

Calculation
scores = [10, 20, 30]
initialValue = 0

in: { $add: ["$$value", "$$this"] }

  start     $$value = 0
  + 10   →  $$value = 10
  + 20   →  $$value = 30
  + 30   →  $$value = 60

final → 60

MongoDB Examples

We use one student with three scores. First insert the sample, then sum with $reduce, then join tags into one string. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine student Asha with quiz scores 10, 20, 30 and tags math / quiz. We save the document in a collection named students.

mongosh
db.students.insertOne({
  _id: 1,
  name: "Asha",
  scores: [10, 20, 30],
  tags: ["math", "quiz"]
});

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps one document in students. Run find() to see it:

mongosh
db.students.find()

Read that document like this:

Field in MongoDBValuePlain English
_id1Document id
name"Asha"Student name
scores[10, 20, 30]Numbers to fold
tags["math", "quiz"]Strings to join later
Picture
scores:  10 → 20 → 30
fold +:   0 → 10 → 30 → 60

tags:    "math" → "quiz"
fold -:  "" → "math" → "math-quiz"

How It Works

  1. Insert once. insertOne adds Asha’s document to students.
  2. Keep arrays ready. scores and tags are what $reduce will walk.
  3. find() shows the same shape. Ready for Example 2.

Example 2 — Sum with $reduce

Goal: add total = sum of scores, starting from 0.

mongosh
db.students.aggregate([
  {
    $addFields: {
      total: {
        $reduce: {
          input: "$scores",
          initialValue: 0,
          in: { $add: ["$$value", "$$this"] }
        }
      }
    }
  }
]);

How It Works

  1. Read the array. input: "$scores" walks [10, 20, 30].
  2. Start at 0. initialValue is the first $$value.
  3. Add each item. $add: ["$$value", "$$this"] builds 0 → 10 → 30 → 60.

Example 3 — Join Strings

Same student, but fold tags into one label with dashes using $concat.

mongosh
db.students.aggregate([
  {
    $addFields: {
      label: {
        $reduce: {
          input: "$tags",
          initialValue: "",
          in: {
            $cond: [
              { $eq: ["$$value", ""] },
              "$$this",
              { $concat: ["$$value", "-", "$$this"] }
            ]
          }
        }
      }
    }
  }
]);

How It Works

  1. Start empty. initialValue: "" means no text yet.
  2. First tag. When $$value is empty, keep $$this alone → "math".
  3. Next tags. Concatenate with "-" → "math-quiz".

Edge Cases & Pitfalls

Check these before folding arrays in production pipelines.

vars

$$value vs $$this

$$value is the running total. $$this is the current element. Mixing them up is the most common mistake.

empty

Empty → initialValue

An empty array never enters in. You get whatever you set as initialValue.

null

Null input → null

Missing or null arrays return null, not initialValue. Guard with $ifNull when needed.

map

Need an array back?

Use $map. $reduce is for collapsing to one value.

Performance Notes

ApproachCostBest for
$reduce on array fieldO(n) per docCustom folds (sum, join, max)
Simple sum onlyOften cheaper builtinsWhen a dedicated operator exists
Huge arraysCPU grows with lengthKeep arrays lean

$reduce visits every element once. That is fine for short arrays; avoid folding very large arrays on hot paths when a simpler operator will do.

Key Takeaways

  • Role: fold an array into one final value.
  • Parts: input + initialValue + in.
  • Vars: $$value (so far) · $$this (current).
  • Sample: [10, 20, 30] → total 60.

One line: $reduce answers “walk this array and keep updating one accumulator until one answer remains.”

Frequently Asked Questions

$reduce folds an array into a single value by walking each element and updating an accumulator. It is like JavaScript’s Array.reduce() inside an aggregation expression.
Use { $reduce: { input: <array>, initialValue: <expression>, in: <expression> } }. Inside in, $$value is the accumulator and $$this is the current element.
Use $$value for the running result and $$this for the current array item. Both need the double-dollar prefix.
$reduce returns initialValue. No elements run, so the accumulator never changes.
$map returns a new array with one result per element. $reduce returns one final value—sum, max, joined string, and so on.
If input is null or missing, $reduce returns null.

Next: $regex

Filter documents with pattern matching on string fields.

$regex tutorial →

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.

9 people found this page helpful