The $addFields stage adds new computed fields to each document in a pipeline while keeping existing fields—ideal for line totals, formatted labels, flags, and derived metrics before sorting or grouping.
01
Add columns
Keep all existing fields.
02
Expressions
$multiply, $concat, $cond.
03
vs $project
Additive vs reshape.
04
$set alias
Same syntax since 4.2.
05
Nested fields
Dot notation merge.
06
Pipeline order
Often after $match.
Fundamentals
Definition and Usage
$addFields is an aggregation stage that outputs documents equal to the input documents plus any fields you define. Each new field’s value comes from an aggregation expression evaluated against the current document.
💡
Beginner tip
Think of $addFields as adding spreadsheet columns without deleting the originals. If you need to drop fields or show only a subset, use $project instead.
Use $addFields when downstream stages need calculated values—totals for $sort, categories for $group, or display strings before $limit. Pair with operators like $add and $multiply inside expressions.
Foundation
📝 Syntax
$addFields takes a document mapping field names to expressions:
You can add multiple fields in one $addFields stage—later fields can reference earlier ones only if you split into two stages (each stage sees prior output).
Compare
📋 $addFields vs related stages
Stage
Effect
Best for
$addFields
Add/replace fields; keep others
Computed columns on full documents
$set
Alias of $addFields
Same; newer naming preference
$project
Include/exclude/rename fields
Sliding output shape, hide _id, pick columns
$unset
Remove fields
Drop sensitive or unused columns
$replaceWith
Replace entire document
Full document transform
🧠 How $addFields Works
1
Documents enter stage
Each document from the previous pipeline stage is processed independently.
Input
2
Expressions evaluated
MongoDB computes every value in the $addFields object against the current document.
Eval
3
Fields merged
New fields are merged onto the document copy. Name collisions overwrite the old value.
Merge
=
➕
Enriched documents out
Downstream stages receive documents with the added fields available.
Important
📝 Notes
$addFields does not write to the collection—it transforms documents in the pipeline only.
To reference a field added in the same stage, use a second$addFields stage—expressions in one object cannot refer to sibling keys being defined simultaneously.
$set and $addFields are interchangeable on MongoDB 4.2+.
Dot-notation keys merge into nested objects; they do not replace the entire parent object unless intended.
Place before $group when grouped accumulators need the computed field (e.g. group by lineTotal bucket).
$addFields is the go-to stage for enriching documents with computed columns without dropping existing data. Map field names to expressions, chain stages as needed, and follow with $sort or $group.
When you only need a slim result set, combine with $project. When replacing the whole document, consider $replaceWith. Next: $bucket for categorical grouping.
Use $addFields when you need a few computed columns on full documents
Put $match first to reduce documents before expensive expressions
Split dependent calculations across consecutive $addFields stages
Name fields clearly: lineTotal, fullName, isActive
Use $project at the end to trim fields for API responses
❌ Don’t
Use $addFields when you only need three fields—$project may be clearer
Assume sibling fields in one $addFields object can reference each other
Overwrite _id unintentionally with the same field name
Confuse pipeline $addFields with update operator $set on a single document
Store heavy nested objects when a flat field suffices
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about $addFields
Use these points whenever you enrich documents mid-pipeline.
5
Core concepts
➕01
Add fields
Keep existing docs.
Basics
📦02
Expressions
Any operator allowed.
Syntax
📄03
vs $project
Add vs reshape.
Compare
🔄04
$set alias
Same behavior.
Tip
🛠05
Pipeline order
Match → add → sort.
Pattern
❓ Frequently Asked Questions
$addFields adds one or more new fields to every document passing through the stage. All existing fields are kept unless you assign to the same field name—then the new expression replaces that field's value.
Anywhere in an aggregation pipeline where you need computed columns: { $addFields: { lineTotal: { $multiply: ["$price", "$quantity"] } } }. Common after $match and before $sort or $group.
$project reshapes output—you must explicitly include fields you want to keep (or use inclusion/exclusion rules). $addFields is additive: existing fields stay by default, so it is faster to write when you only need a few new columns.
Yes. MongoDB 4.2+ treats $set as an alias for $addFields—they accept the same syntax and behave identically.
Yes. Use dot notation as the key ("address.city") or nest objects: { address: { city: "$cityName" } }. Dot notation merges into existing nested objects when present.
Absolutely. Values can be field paths, literals, or any expression—$add, $multiply, $concat, $cond, $dateToString, and more.
Did you know?
Before $addFields existed, developers simulated it with $project using fieldName: 1 for every existing field plus the new expression—a verbose pattern that was easy to get wrong. $addFields (MongoDB 3.4+) made additive transforms a first-class stage. See the official $addFields docs.