Aggregation Expressions
Aggregation expressions are the operators and functions used inside pipeline stages to compute values. They cover arithmetic, strings, dates, conditionals, arrays, type conversion, and more.
Expression Syntax
Expression basics
// Field reference — prefix field name with $
'$price' // value of the price field
// Operator expression
{ $add: ['$price', '$tax'] }
{ $multiply: ['$quantity', '$unitPrice'] }
// Nested expressions
{ $multiply: ['$quantity', { $subtract: ['$price', '$discount'] }] }Arithmetic Operators
Operator | Description | Example |
|---|---|---|
$add | Sum | { $add: ['$a', '$b'] } |
$subtract | Difference | { $subtract: ['$revenue', '$cost'] } |
$multiply | Product | { $multiply: ['$price', '$qty'] } |
$divide | Quotient | { $divide: ['$total', '$count'] } |
$mod | Remainder | { $mod: ['$value', 2] } |
$abs | Absolute value | { $abs: '$delta' } |
$ceil | Round up | { $ceil: '$score' } |
$floor | Round down | { $floor: '$score' } |
$round | Round to N decimals | { $round: ['$price', 2] } |
$sqrt | Square root | { $sqrt: '$area' } |
$pow | Power | { $pow: ['$base', 2] } |
Arithmetic in $project
{
$project: {
discountedPrice: { $multiply: ['$price', 0.9] },
profit: { $subtract: ['$revenue', '$cost'] },
avgPerUnit: { $divide: ['$total', '$units'] },
marginPct: {
$round: [
{ $multiply: [{ $divide: ['$profit', '$revenue'] }, 100] },
1,
],
},
},
}String Operators
String expressions
{ $concat: ['$first', ' ', '$last'] }
{ $toUpper: '$country' }
{ $toLower: '$email' }
{ $trim: { input: '$username' } }
{ $ltrim: { input: '$code', chars: '0' } }
{ $substr: ['$sku', 0, 4] } // first 4 chars
{ $strLenCP: '$description' } // char count
{ $split: ['$csv', ','] } // split to array
{ $indexOfCP: ['$path', '/'] } // find position
{ $regexMatch: { input: '$email', regex: /@gmail\.com$/ } }Date Operators
Date expressions
{ $year: '$createdAt' }
{ $month: '$createdAt' } // 1–12
{ $dayOfMonth: '$createdAt' } // 1–31
{ $dayOfWeek: '$createdAt' } // 1 (Sun) – 7 (Sat)
{ $hour: '$createdAt' }
{ $minute: '$createdAt' }
// Format as string
{ $dateToString: { format: '%Y-%m-%d', date: '$createdAt' } }
// Date arithmetic (MongoDB 5.0+)
{ $dateAdd: { startDate: '$createdAt', unit: 'day', amount: 30 } }
{
$dateDiff: {
startDate: '$createdAt',
endDate: '$$NOW',
unit: 'day',
},
}Conditional Expressions
$cond — ternary
// if score >= 90 then 'A' else 'B'
{
$cond: {
if: { $gte: ['$score', 90] },
then: 'A',
else: 'B',
},
}$switch — multiple branches
{
$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',
},
}$ifNull — null coalescing
// Return nickname if present, otherwise firstName
{ $ifNull: ['$nickname', '$firstName'] }
// Chain multiple fallbacks
{ $ifNull: ['$displayName', '$username', 'Anonymous'] }Array Expressions
Array expressions
{ $size: '$tags' } // array length
{ $arrayElemAt: ['$scores', 0] } // first element
{ $first: '$scores' } // first (shorthand)
{ $last: '$scores' } // last
// Filter array elements
{
$filter: {
input: '$items',
as: 'item',
cond: { $gt: ['$$item.price', 50] },
},
}
// Transform each element
{ $map: { input: '$prices', as: 'p', in: { $multiply: ['$$p', 1.1] } } }
// Compute a single value from array
{
$reduce: {
input: '$scores',
initialValue: 0,
in: { $add: ['$$value', '$$this'] },
},
}
{ $concatArrays: ['$tags', '$categories'] }
{ $setIntersection: ['$userRoles', '$requiredRoles'] }
{ $setUnion: ['$listA', '$listB'] }
{ $range: [0, 10, 2] } // [0, 2, 4, 6, 8]Accumulator Operators (in $group)
Operator | Purpose |
|---|---|
$sum | Sum numeric values (or count with 1) |
$avg | Arithmetic mean |
$min / $max | Minimum / maximum value |
$first / $last | First / last value in the group |
$push | Build array of all values in group |
$addToSet | Build array of unique values |
$stdDevPop | Population standard deviation |
$stdDevSamp | Sample standard deviation |
$mergeObjects | Merge subdocuments into one |
Type Conversion
Type conversion operators
{ $toInt: '$stringNumber' }
{ $toString: '$objectId' }
{ $toDouble: '$intField' }
{ $toDate: '$isoString' }
{ $toBool: '$intFlag' }
// $convert with error handling
{
$convert: {
input: '$maybeNumber',
to: 'int',
onError: 0, // fallback if conversion fails
onNull: -1, // fallback if field is null/missing
},
}