Aggregation Expressions
Conditional Expressions
$cond, $ifNull and $switch for branching inside a pipeline.
$match drops documents. `$cond` keeps the document and picks a value. Labels, defaults, and conditional totals all live here — not in a second query from Node.
db.products.aggregate([
{
$set: {
band: {
$cond: { if: { $gte: ["$price", 4000] }, then: "premium", else: "standard" }
}
}
}
])
// same: { $cond: [{ $gte: ["$price", 4000] }, "premium", "standard"] }{ name: "Mechanical Keyboard", price: 4500, band: "premium" }
{ name: "USB-C Cable", price: 200, band: "standard" }{ $ifNull: ["$discount", 0] }
{
$switch: {
branches: [
{ case: { $eq: ["$status", "cancelled"] }, then: 0 },
{ case: { $eq: ["$status", "pending"] }, then: "$amount" }
],
default: "$amount"
}
}db.orders.aggregate([
{
$group: {
_id: "$userId",
paid: {
$sum: {
$cond: [{ $ne: ["$status", "cancelled"] }, "$amount", 0]
}
}
}
}
])$ifNull treats missing and null as the default. A real 0 is kept. Nested $cond works; $switch is what you write when the fourth branch appears. $eq / $gte here are expressions (array operands), not { status: "cancelled" } query syntax — that filter form does not work inside $cond.
Interview question
When do you use $cond instead of $match?
$match drops documents. $cond keeps every document and chooses a value — a label, a default, or 0 vs amount inside $sum. $ifNull fills missing or null. $switch when there are more than two branches. Inside $cond, comparisons are expressions: { $eq: ["$status", "cancelled"] }, not query syntax.