$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:

  1. {
  2. $let:
  3. {
  4. vars: { <var1>: <expression>, ... },
  5. in: <expression>
  6. }
  7. }

FieldSpecificationvarsAssignment block for the variables accessible in the inexpression. 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 inexpression, not even within the vars block itself.inThe 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 inexpression. 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:

  1. {
  2. $let:
  3. {
  4. vars: { low: 1, high: "$$low" },
  5. in: { $gt: [ "$$low", "$$high" ] }
  6. }
  7. }

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:

  1. { _id: 1, price: 10, tax: 0.50, applyDiscount: true }
  2. { _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:

  1. db.sales.aggregate( [
  2. {
  3. $project: {
  4. finalTotal: {
  5. $let: {
  6. vars: {
  7. total: { $add: [ '$price', '$tax' ] },
  8. discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
  9. },
  10. in: { $multiply: [ "$$total", "$$discounted" ] }
  11. }
  12. }
  13. }
  14. }
  15. ] )

The aggregation returns the following results:

  1. { "_id" : 1, "finalTotal" : 9.450000000000001 }
  2. { "_id" : 2, "finalTotal" : 10.25 }

See also

$map