$let is a MongoDB aggregation expression that defines local variables, then evaluates one final expression that can use them. Compute a value once, give it a name, and reuse it with $$name.
Remember
$let = name a value, then use it
{ $let: {
vars: { total: { $multiply: ["$price", "$qty"] } },
in: "$$total"
}
}
$price → document field
$$total → $let variable
vars run first → then in
In vars, name each temporary value (for example total = price × qty).
In in, build the final result using $$total (double dollar).
Keep variable names short and clear—they exist only inside this $let.
Piece
Required?
Role
vars
Yes
Map of variable name → expression
in
Yes
Final expression using $$vars
$$name
In in
Read a variable from vars
Pseudocode
Pseudocode
for each document:
// evaluate vars (can read document fields with $)
total = price * qty
// evaluate in (can read vars with $$)
result = total // or total - discount, etc.
emit { ..., field: result }
Reference
Cheat Sheet
Keep these facts handy while naming aggregation variables.
Topic
Detail
Type
Aggregation expression (not a find filter)
Syntax
{ $let: { vars: {...}, in: <expr> } }
Field vs var
$price field · $$total variable
Scope
Variables live only inside this $let
Order
vars first, then in
Reuse tip
Compute once when used more than once
Sample
price 50 × qty 3 → total 150
Try it
Live Preview
Watch $let compute total = price × qty, then optionally subtract a discount in in.
One order line: a Notebook costs 50 and quantity is 3. We name that product total, then reuse it.
Calculation
Document:
{ item: "Notebook", price: 50, qty: 3 }
vars:
total = $multiply(["$price", "$qty"])
= 50 × 3
= 150
in (example A): "$$total" → 150
in (example B): $$total − 20 → 130
Without $let you would write multiply twice.
With $let you compute once and reuse $$total.
Code
MongoDB Examples
We use one order line. First store the sample, then compute total with $let, then reuse it for a discount. Run these in mongosh after inserting the sample data once.
Example 1 — Sample Data
Imagine one order line for a Notebook priced at 50 with quantity 3. We save it in a collection named orders.
Check these before nesting variables in production pipelines.
prefix
$ vs $$
$price is a document field. $$total is a $let variable. Mixing them up is the most common beginner mistake.
scope
Variables do not leak
$$total exists only inside that $let. Later stages cannot see it unless you write the result to a real field.
order
vars cannot use each other
One vars entry cannot reference another sibling with $$. Nest a second $let if you need a chain.
null
Null inputs flow through
If $price or $qty is null/missing, $multiply yields null and $$total becomes null.
Analysis
Performance Notes
Approach
Cost
Best for
$let + reuse
Compute once
Shared sub-expressions
Repeat $multiply
Same work twice
Only if used once
Store field earlier
Extra field in pipeline
Value needed in many stages
$let is about clarity and avoiding duplicate work inside one expression. If many later stages need the value, write it once with $addFields instead.
Remember
Key Takeaways
Role: name local values inside one expression.
Syntax:vars + in; read with $$name.
Reuse: compute once when the value is used more than once.
Sample: 50 × 3 → $$total 150 → discount 130.
One line:$let answers “compute this once, name it, then use $$name in the final expression.”
Frequently Asked Questions
$let defines local variables inside an aggregation expression, then evaluates an in expression that can use those variables. It lets you compute a value once and reuse it with a clear name.
Use { $let: { vars: { <name>: <expression>, ... }, in: <expression> } }. Inside in, reference each variable with a double dollar prefix, such as "$$total".
Use $$name. A single $ means a document field ("$price"). Double $$ means a variable from $let (or from operators like $map / $filter).
Yes. You can put a $let inside another $let's in expression. An inner variable with the same name shadows the outer one.
Anywhere an aggregation expression is allowed—$addFields, $project, $set, and inside other expressions such as $cond or $multiply.
Use $let when the same sub-expression appears more than once, or when a named step makes the pipeline easier to read—for example price × qty reused for a discount.