$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
Build a branches array of { case, then } objects (at least one).
Write each case as a boolean expression (often with $gte / $lt).
Add default for the “nothing matched” path.
Piece
Required?
Role
branches
Yes
Ordered list of case/then pairs
case
Yes (per branch)
Boolean test for that branch
then
Yes (per branch)
Result when that case is true
default
Strongly yes
Result 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 }
Reference
Cheat Sheet
Keep these facts handy while writing multi-branch conditions.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $switch: { branches: [...], default: <expr> } }
Order
First true case wins
No match
Uses default; without it → error
vs $cond
Many branches vs one if/else
Grade pattern
≥ 90 → A, ≥ 80 → B, else default
Sample check
score 85 → first of A/B/C that matches → "B"
Try it
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" }
Trace
Worked Walkthrough — Score 85
One student scored 85. We map that to a letter grade with ordered $gte branches.
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.
Same stored students. Still using scores 85 and 95 from Example 1.
Same branch order. Highest band first so 95 does not fall into the 80+ message.
then holds any expression. Here each branch returns a string message.
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.
Analysis
Performance Notes
Approach
Cost
Best for
$switch with few branches
Per document, short-circuits on first match
Grades, statuses, buckets
Deep nested $cond
Similar CPU, harder to maintain
Avoid for 3+ outcomes
$match then $switch
Fewer docs to evaluate
Only some rows need labels
Branch evaluation is cheap for short lists. Filter early with $match when only some documents need a label.
Remember
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.