$let (aggregation)
Definition
$let
- Binds variables for use inthe specified expression, and returns the result of the expression.
The $let
expression has the following syntax:
- {
- $let:
- {
- vars: { <var1>: <expression>, ... },
- in: <expression>
- }
- }
FieldSpecificationvars
Assignment block for the variables accessible in the in
expression. To assign a variable, specify a string for thevariable name and assign a valid expression for the value.
The variable assignments have no meaning outside the in
expression, not even within the vars
block itself.in
The expression to evaluate.
To access variables in aggregation expressions, prefix the variablename with double dollar signs ($$
) and enclosed in quotes. Formore information on expressions, seeExpressions. For information on use ofvariables in the aggregation pipeline, seeVariables in Aggregation Expressions.
Behavior
$let
can access variables defined outside its expressionblock, including system variables.
If you modify the values of externally defined variables in thevars
block, the new values take effect only in the in
expression. Outside of the in
expression, the variables retaintheir previous values.
In the vars
assignment block, the order of the assignment doesnot matter, and the variable assignments only have meaning insidethe in
expression. As such, accessing a variable’s value in thevars
assignment block refers to the value of the variable definedoutside the vars
block and not inside the same vars
block.
For example, consider the following $let
expression:
- {
- $let:
- {
- vars: { low: 1, high: "$$low" },
- in: { $gt: [ "$$low", "$$high" ] }
- }
- }
In the vars
assignment block, "$$low"
refers to the value of anexternally defined variable low
and not the variable defined in thesame vars
block. If low
is not defined outside this$let
expression block, the expression is invalid.
Example
A sales
collection has the following documents:
- { _id: 1, price: 10, tax: 0.50, applyDiscount: true }
- { _id: 2, price: 10, tax: 0.25, applyDiscount: false }
The following aggregation uses $let
in the$project
pipeline stage to calculate and return thefinalTotal
for each document:
- db.sales.aggregate( [
- {
- $project: {
- finalTotal: {
- $let: {
- vars: {
- total: { $add: [ '$price', '$tax' ] },
- discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
- },
- in: { $multiply: [ "$$total", "$$discounted" ] }
- }
- }
- }
- }
- ] )
The aggregation returns the following results:
- { "_id" : 1, "finalTotal" : 9.450000000000001 }
- { "_id" : 2, "finalTotal" : 10.25 }
See also