MongoDB $let Operator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $let?

$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
UsePrefer
Name & reuse a sub-expression$let
Keep a literal as-is$literal
Read a field by dynamic name$getField

How to Use $let in MongoDB

Define variables in vars, then return a result from in.

  1. Choose an expression stage ($addFields or $project).
  2. In vars, name each temporary value (for example total = price × qty).
  3. In in, build the final result using $$total (double dollar).
  4. Keep variable names short and clear—they exist only inside this $let.
PieceRequired?Role
varsYesMap of variable name → expression
inYesFinal expression using $$vars
$$nameIn inRead 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 }

Cheat Sheet

Keep these facts handy while naming aggregation variables.

TopicDetail
TypeAggregation expression (not a find filter)
Syntax{ $let: { vars: {...}, in: <expr> } }
Field vs var$price field · $$total variable
ScopeVariables live only inside this $let
Ordervars first, then in
Reuse tipCompute once when used more than once
Sampleprice 50 × qty 3 → total 150

Live Preview

Watch $let compute total = price × qty, then optionally subtract a discount in in.

Simulates { $let: { vars: { total: … }, in: … } }.

Result
document = { price: 50, qty: 3 }

vars:
  total = 50 × 3 → 150

in:
  $$total → 150

result → 150

Worked Walkthrough — Line Total

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.

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.

mongosh
db.orders.insertOne({
  _id: 1,
  item: "Notebook",
  price: 50,
  qty: 3
});

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps one document in orders. Run find() to see it:

mongosh
db.orders.find()

Read that document like this:

Field in MongoDBValuePlain English
_id1Document id
item"Notebook"What was ordered
price50Unit price
qty3How many units
Picture
price 50  ×  qty 3  →  total 150

$let names that 150 as $$total
so later steps can reuse it

How It Works

  1. Insert once. insertOne adds a single order line to orders.
  2. Keep price and qty separate. We will multiply them inside $let next.
  3. find() shows the same shape. Ready for Example 2.

Example 2 — Name a Total

Goal: compute lineTotal as price × qty using a $let variable named total.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      lineTotal: {
        $let: {
          vars: {
            total: { $multiply: ["$price", "$qty"] }
          },
          in: "$$total"
        }
      }
    }
  }
]);

How It Works

  1. Read the fields. $price is 50 and $qty is 3 from Example 1.
  2. Name the product. vars.total becomes 50 × 3 = 150.
  3. Return it. in: "$$total" writes lineTotal: 150.

Example 3 — Reuse for Discount

Same order, but now in subtracts a flat discount of 20 from the named total—without multiplying twice.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      afterDiscount: {
        $let: {
          vars: {
            total: { $multiply: ["$price", "$qty"] }
          },
          in: { $subtract: ["$$total", 20] }
        }
      }
    }
  }
]);

How It Works

  1. Same stored document. Still using price 50 and qty 3 from Example 1.
  2. Compute once. $$total is 150 from $multiply.
  3. Reuse in in. $subtract does 150 − 20 → 130.

Edge Cases & Pitfalls

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.

Performance Notes

ApproachCostBest for
$let + reuseCompute onceShared sub-expressions
Repeat $multiplySame work twiceOnly if used once
Store field earlierExtra field in pipelineValue 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.

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.

Next: $literal

Embed literal values safely inside aggregation expressions.

$literal tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful