MongoDB $switch: Syntax, Examples, and $cond Comparison
MongoDB $switch is an aggregation expression for multi-branch conditional logic. It evaluates branches in order and returns the then expression from the first branch whose case evaluates to true.
Use $switch when a result depends on several conditions. For a simple if/else decision, $cond is usually shorter.
Syntax
{
$switch: {
branches: [
{ case: <expression>, then: <expression> },
{ case: <expression>, then: <expression> }
],
default: <expression>
}
}
Important behavior:
branchesmust contain at least one branch.- Each branch contains only
caseandthen. - MongoDB evaluates branches from top to bottom.
- The first true branch wins, even if later conditions would also be true.
defaultis optional, but if it is omitted and no branch matches, MongoDB returns an error.
Example: classify scores
Suppose a students collection contains:
{ "_id": 1, "name": "Ana", "score": 92 }
{ "_id": 2, "name": "Ben", "score": 76 }
{ "_id": 3, "name": "Cara", "score": 61 }
Use $switch inside $project to create a grade band:
db.students.aggregate([
{
$project: {
name: 1,
score: 1,
grade: {
$switch: {
branches: [
{ case: { $gte: ["$score", 90] }, then: "A" },
{ case: { $gte: ["$score", 80] }, then: "B" },
{ case: { $gte: ["$score", 70] }, then: "C" },
{ case: { $gte: ["$score", 60] }, then: "D" }
],
default: "F"
}
}
}
}
])
The result is equivalent to:
{ "_id": 1, "name": "Ana", "score": 92, "grade": "A" }
{ "_id": 2, "name": "Ben", "score": 76, "grade": "C" }
{ "_id": 3, "name": "Cara", "score": 61, "grade": "D" }The ordering matters. If the score >= 60 branch appeared first, a score of 92 would match that branch before MongoDB reached score >= 90.
Example: return values from document fields
Both case and then accept aggregation expressions:
db.orders.aggregate([
{
$project: {
total: 1,
shippingTier: {
$switch: {
branches: [
{ case: { $gte: ["$total", 200] }, then: "free-express" },
{ case: { $gte: ["$total", 75] }, then: "free-standard" }
],
default: "paid-standard"
}
}
}
}
])
$switch vs $cond
Use $cond for one condition with two outcomes:
{
$cond: [
{ $gte: ["$total", 75] },
"free-shipping",
"paid-shipping"
]
}
Use $switch when you would otherwise nest several $cond expressions. It is easier to read and makes branch priority explicit.
Common mistakes
Omitting default when no branch is guaranteed to match
This can fail at runtime:
{
$switch: {
branches: [
{ case: { $eq: ["$status", "paid"] }, then: 1 }
]
}
}
Add a default unless your data guarantees one branch always matches.
Putting broad conditions before specific conditions
Because the first true branch wins, put the most specific or highest-priority conditions first.
Using $switch as a query filter
$switch is an aggregation expression. Use it inside stages such as $project, $set, or expression contexts. For ordinary document filtering, query operators are usually more direct.