MongoDB $addFields Stage

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

What Is $addFields?

$addFields is a MongoDB aggregation stage that adds one or more computed fields to every document. Existing fields stay by default—so it is the easy way to append columns like lineTotal without rebuilding the whole document.

Remember
$addFields = add columns, keep the rest

{ $addFields: { <field>: <expression>, ... } }

keeps all existing fields
same name → overwrites that field
$set → alias for $addFields

vs $project → reshape / pick fields
new fields → visible to later stages
UsePrefer
Add computed columns$addFields (or $set)
Slim / reshape output$project
Filter before computing$match then $addFields

How to Use $addFields in MongoDB

Name the new fields, give each an expression, and place the stage where later steps need those values.

  1. Start (or continue) an aggregation pipeline with aggregate([...]).
  2. Add { $addFields: { fieldName: <expression> } }.
  3. Use field paths like "$price" and operators like $multiply.
  4. Use the new fields in later stages ($sort, $group, another $project).
PieceRequired?Role
Field nameYesNew (or replaced) key on the document
ExpressionYesLiteral, field path, or aggregation expression
Multiple fieldsNoAdd several keys in one stage

Pseudocode

Pseudocode
for each document:
    out = copy(document)          // keep existing fields
    for each (field, expression) in $addFields:
        out[field] = evaluate(expression)
    emit out

Cheat Sheet

Keep these facts handy while adding fields in a pipeline.

TopicDetail
TypeAggregation stage (not a find filter)
Syntax{ $addFields: { <field>: <expression> } }
Alias$set (same behavior)
DefaultKeeps all existing fields
Same nameOverwrites that field
Nested fieldsDot path: "address.city"
vs $projectAdditive vs reshape

Live Preview

Watch $addFields append lineTotal = price × quantity while keeping the original fields.

Simulates $addFields: { lineTotal: { $multiply: ["$price", "$quantity"] } }.

Result
input:
  { product: "Keyboard", price: 45, quantity: 2 }

$multiply → 45 * 2 = 90

output (+ keeps original fields):
  { product: "Keyboard", price: 45, quantity: 2, lineTotal: 90 }

Worked Walkthrough — Line Total

One order has price: 45 and quantity: 2. Goal: add lineTotal without dropping other fields.

Calculation
Document in:
  { product: "Keyboard", price: 45, quantity: 2 }

$addFields:
  lineTotal: { $multiply: ["$price", "$quantity"] }

45 * 2 = 90

Document out:
  {
    product: "Keyboard",
    price: 45,
    quantity: 2,
    lineTotal: 90      // new
  }

MongoDB Examples

We use a small orders collection. First add a line total, then add two fields in one stage. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine three order lines with product, price, quantity, and a customer first/last name.

mongosh
db.orders.insertMany([
  {
    _id: 1,
    product: "Keyboard",
    price: 45,
    quantity: 2,
    firstName: "Sam",
    lastName: "Lee"
  },
  {
    _id: 2,
    product: "Mouse",
    price: 25,
    quantity: 1,
    firstName: "Alex",
    lastName: "Kim"
  },
  {
    _id: 3,
    product: "Monitor",
    price: 180,
    quantity: 1,
    firstName: "Jordan",
    lastName: "Wu"
  }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps three documents in orders. Run find() to see them:

mongosh
db.orders.find()

Read each document like this:

Field in MongoDBExamplePlain English
product"Keyboard"Item name
price45Unit price
quantity2Units ordered
firstName / lastNameSam / LeeCustomer name parts

How It Works

  1. Insert once. insertMany adds three order documents to orders.
  2. Fields stay as written. Price and quantity are numbers; names are strings.
  3. find() shows the same shape. Ready for $addFields next.

Example 2 — Add lineTotal

Goal: append lineTotal = price × quantity on every order without removing other fields.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      lineTotal: { $multiply: ["$price", "$quantity"] }
    }
  }
]);

How It Works

  1. Read stored numbers. Keyboard has price: 45 and quantity: 2 from Example 1.
  2. Compute the expression. $multiply returns 90.
  3. Keep everything else. $addFields appends lineTotal; names and product stay on the document.

Example 3 — Add Multiple Fields

Same orders, but add lineTotal and fullName in one $addFields stage.

mongosh
db.orders.aggregate([
  {
    $addFields: {
      lineTotal: { $multiply: ["$price", "$quantity"] },
      fullName: {
        $concat: ["$firstName", " ", "$lastName"]
      }
    }
  }
]);

How It Works

  1. Same stored documents. Still using the three orders from Example 1.
  2. Two expressions, one stage. Multiply for the total; $concat for the name.
  3. Still additive. Original fields remain; both new fields appear together.
  4. Easy check. Keyboard should show lineTotal: 90 and fullName: "Sam Lee".

Edge Cases & Pitfalls

Check these before using $addFields in production pipelines.

overwrite

Same name replaces the field

If you write price: { $multiply: ["$price", 1.1] }, the old price is gone. Use a new name when you need both values.

order

Stage order matters

Fields added here are invisible to earlier stages. Put $addFields before any stage that must read the new field.

shape

Not a slim reshape tool

To drop unused fields for an API response, follow with $project (or use $project alone).

alias

$set is the same stage

$set is an alias for $addFields. Pick one style and stay consistent in a codebase.

Performance Notes

ApproachCostBest for
$addFields alonePer-document expressionsA few computed columns
$match then $addFieldsFewer docs to computeLarge collections
Late $projectTrim after computeSlim API responses

Expression work is usually cheap compared with large sorts or joins. Filter early with $match when only some documents need the new fields.

Key Takeaways

  • Role: add computed fields; keep the rest.
  • Alias: $set behaves the same.
  • vs $project: additive vs reshape.
  • Overwrite: reusing a field name replaces it.

One line: $addFields answers “add these computed columns—and leave the rest of the document alone.”

Frequently Asked Questions

$addFields adds one or more new fields to every document in an aggregation pipeline. Existing fields stay unless you reuse the same field name—then the new expression replaces that field.
Use { $addFields: { <newField>: <expression>, ... } }. Each value can be a field path, a literal, or any aggregation expression such as $multiply or $concat.
$addFields is additive—original fields remain by default. $project reshapes the document; you generally list only the fields you want to keep.
Yes. In modern MongoDB, $set is an alias for $addFields. They share the same syntax and behavior.
Yes. If the new field name matches an existing one, $addFields replaces that field’s value with the expression result.
Anywhere you need computed columns—often after $match and before $sort, $group, or a final $project. Later stages can use the new fields.

Next: $bucket

Group documents into buckets based on numeric ranges in a pipeline.

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