MongoDB $switch Operator

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

What Is $switch?

$switch is a MongoDB aggregation expression that picks a result from an ordered list of case / then branches—like a switch statement. The first true case wins. If none match, use default (or the pipeline errors).

Remember
$switch = multi-branch if / else if / else for aggregation

{
  $switch: {
    branches: [
      { case: <bool expr>, then: <value> },
      { case: <bool expr>, then: <value> }
    ],
    default: <value>   // strongly recommended
  }
}

first true case wins
no match + no default → pipeline error
one if/else → prefer $cond
UsePrefer
Many outcomes (A / B / C / …)$switch
One true/false fork$cond
Compare numbers in a case$gte / $lt / $eq
Fill missing values$ifNull

How to Use $switch in MongoDB

List branches from most specific to most general, then always set a default.

  1. Choose an expression stage ($addFields or $project).
  2. Build a branches array of { case, then } objects (at least one).
  3. Write each case as a boolean expression (often with $gte / $lt).
  4. Add default for the “nothing matched” path.
PieceRequired?Role
branchesYesOrdered list of case/then pairs
caseYes (per branch)Boolean test for that branch
thenYes (per branch)Result when that case is true
defaultStrongly yesResult when no case matches

Pseudocode

Pseudocode
for each document:
    for each branch in branches (top to bottom):
        if evaluate(branch.case) is true:
            result = evaluate(branch.then)
            break
    if no branch matched:
        if default exists:
            result = evaluate(default)
        else:
            error
    emit { ..., field: result }

Cheat Sheet

Keep these facts handy while writing multi-branch conditions.

TopicDetail
TypeAggregation expression (not a find filter)
Syntax{ $switch: { branches: [...], default: <expr> } }
OrderFirst true case wins
No matchUses default; without it → error
vs $condMany branches vs one if/else
Grade pattern≥ 90 → A, ≥ 80 → B, else default
Sample checkscore 85 → first of A/B/C that matches → "B"

Live Preview

Watch $switch map a score to a letter grade. Branches are checked from A toward F.

Simulates $switch letter grades (same idea as the mongosh examples below).

Result
score = 85

case ≥ 90 → false
case ≥ 80 → true  → "B"

{ grade: "B" }

Worked Walkthrough — Score 85

One student scored 85. We map that to a letter grade with ordered $gte branches.

Calculation
Document:
  { name: "Ada", score: 85 }

Branches (top → bottom):
  score ≥ 90 ? → A   → 85 ≥ 90? false
  score ≥ 80 ? → B   → 85 ≥ 80? true  ✓ stop
  score ≥ 70 ? → C   (not checked)
  default      → F

Result:
  "B"

Check: 80 ≤ 85 < 90 → B ✓

MongoDB Examples

We store two students with scores. First we assign letter grades with $switch, then we show a short status message using default. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine two students: Ada with score 85, and Bob with score 95. We save them in a collection named students.

mongosh
db.students.insertMany([
  { _id: 1, name: "Ada", score: 85 },
  { _id: 2, name: "Bob", score: 95 }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps two documents in students. Run find() to see them:

mongosh
db.students.find()

Read those documents like this:

Field in MongoDBValuePlain English
score (Ada)85Should map to grade B
score (Bob)95Should map to grade A
Picture
Rules (first match wins):
  ≥ 90 → A
  ≥ 80 → B
  ≥ 70 → C
  else → F

Ada 85 → B
Bob 95 → A

How It Works

  1. Insert once. insertMany adds Ada and Bob to students.
  2. Scores are plain numbers. Ready for $gte tests in $switch.
  3. find() shows the same shape. What you inserted is what you get back—ready for grading next.

Example 2 — Letter Grade with $switch

Goal: map each score to A, B, C, or F using ordered branches and a default.

mongosh
db.students.aggregate([
  {
    $addFields: {
      grade: {
        $switch: {
          branches: [
            { case: { $gte: ["$score", 90] }, then: "A" },
            { case: { $gte: ["$score", 80] }, then: "B" },
            { case: { $gte: ["$score", 70] }, then: "C" }
          ],
          default: "F"
        }
      }
    }
  }
]);

How It Works

  1. Read each score. Ada has 85; Bob has 95.
  2. Test A first. $gte 90 fails for Ada, succeeds for Bob → "A".
  3. Ada hits B. 85 ≥ 80 is true, so Ada gets "B" and later branches are skipped.
  4. Default is the safety net. Scores below 70 become "F" instead of erroring.

Example 3 — Status Message

Same idea with friendlier messages. Still one $switch, still first-match wins.

mongosh
db.students.aggregate([
  {
    $addFields: {
      status: {
        $switch: {
          branches: [
            {
              case: { $gte: ["$score", 90] },
              then: "Doing great!"
            },
            {
              case: { $gte: ["$score", 80] },
              then: "Doing pretty well."
            },
            {
              case: { $gte: ["$score", 70] },
              then: "Keep practicing."
            }
          ],
          default: "Needs improvement."
        }
      }
    }
  }
]);

How It Works

  1. Same stored students. Still using scores 85 and 95 from Example 1.
  2. Same branch order. Highest band first so 95 does not fall into the 80+ message.
  3. then holds any expression. Here each branch returns a string message.
  4. default covers low scores. Without it, a 50 would error instead of returning a message.

Edge Cases & Pitfalls

Check these before using $switch in production pipelines.

default

No match without default errors

Unlike some languages that return null, MongoDB fails the aggregation if nothing matches and default is missing.

order

Branch order matters

Put higher thresholds first. If ≥ 80 comes before ≥ 90, a score of 95 becomes B forever.

vs $cond

Do not nest $cond for many paths

For three or more outcomes, $switch stays flatter and easier to read than nested $cond.

shape

Only case and then in each branch

Extra fields inside a branch document, or a missing case/then, cause an error.

Performance Notes

ApproachCostBest for
$switch with few branchesPer document, short-circuits on first matchGrades, statuses, buckets
Deep nested $condSimilar CPU, harder to maintainAvoid for 3+ outcomes
$match then $switchFewer docs to evaluateOnly some rows need labels

Branch evaluation is cheap for short lists. Filter early with $match when only some documents need a label.

Key Takeaways

  • Role: multi-branch case/then picker.
  • Order: first true case wins.
  • Default: always set it to avoid errors.
  • Simple fork: use $cond instead.

One line: $switch answers “which labeled outcome fits this document first?”—with a safe default when none do.

Frequently Asked Questions

$switch evaluates an ordered list of case branches and returns the then value from the first branch whose case is true. If nothing matches, it uses default—or errors if default is omitted. Use it inside aggregation expression stages such as $project and $addFields.
Use { $switch: { branches: [ { case: <expr>, then: <expr> }, ... ], default: <expr> } }. Branches are checked top to bottom; only the first match wins. default is optional but recommended.
$cond is one if-then-else. $switch is many branches in one expression—like a switch/case statement. Prefer $switch over deeply nested $cond when you have several outcomes.
Technically optional, but if you omit default and no case matches, $switch fails with an error. Always provide default unless you are sure a branch will match.
They should resolve to a boolean. If the result is not a boolean, MongoDB coerces it to true/false using its usual truthiness rules.
Yes, but only the first true branch runs. Order your branches from most specific to most general.

Next: $tan

Compute the tangent of an angle in an aggregation pipeline.

$tan 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