Master
$addFields,$count,$merge, and$condwith real-world order data patterns.
| Operator | Description |
|---|---|
$addFields |
Adds new fields or modifies existing fields in each document |
$count |
Counts the number of documents and returns the result as a single doc |
$merge |
Writes aggregation results into a collection |
$cond |
Applies conditional logic (if/then/else) within aggregation expressions |
$field → Single $ references a field in your document
$$variable → Double $$ references aggregation variables (e.g. $$item inside $map)
Goal: Add a field orderCategory where:
"High"→ iftotalAmount > 50000"Low"→ otherwise
$addFieldscomputes a new field without replacing the whole document.$condacts like an if/else — checks the condition, returnsthenorelse.$mergewrites the result back into the sameOrderscollection.whenMatched: 'merge'→ preserves all existing fields, only adds/updatesorderCategory.whenNotMatched: 'discard'→ skips documents that don't already exist in the collection.
db.Orders.aggregate([
{
$addFields: {
orderCategory: {
$cond: {
if: { $gt: ["$totalAmount", 50000] },
then: "High",
else: "Low"
}
}
}
},
{
$merge: {
into: 'Orders',
on: '_id',
whenMatched: 'merge', // keep existing fields, add new one
whenNotMatched: 'discard' // skip if doc not found
}
}
])Each document in Orders now has:
{ "orderCategory": "High" } // totalAmount > 50000
{ "orderCategory": "Low" } // totalAmount <= 50000Goal: Find how many orders have status: "shipped"
$matchfilters the pipeline — only documents matching the condition pass through.$countcollapses all remaining documents into one single output document with the count.
db.Orders.aggregate([
{
$match: {
status: "shipped"
}
},
{
$count: 'totalNumberOfOrders'
}
]){ "totalNumberOfOrders": 42 }Goal: For each order, sum up quantity × price for every item in the items array.
$mapiterates over theitemsarray, giving each element the alias$$item.$$item.priceand$$item.quantityuse$$becauseitemis a variable, not a document field.$multiplycomputesprice × quantityfor each item.$sumadds up all the products from$mapinto a singletotalPrice.$mergewithwhenNotMatched: 'insert'also creates new documents if they don't exist.
db.Orders.aggregate([
{
$addFields: {
totalPrice: {
$sum: {
$map: {
input: "$items", // iterate over the items array
as: "item", // alias each element as $$item
in: {
$multiply: [
"$$item.price", // $$ = variable reference
"$$item.quantity"
]
}
}
}
}
}
},
{
$merge: {
into: 'Orders',
on: '_id',
whenMatched: 'merge',
whenNotMatched: 'insert' // create doc if it doesn't exist
}
}
]){ "totalPrice": 12500 } // sum of (price × qty) for all itemsGoal: Group by customer, sum their spending, then label:
"Premium"→ iftotalSpent > 200000"Regular"→ otherwise
$groupcollapses many documents into one per unique_id(here:customerId).$sum: "$totalAmount"accumulates the running total across all orders for that customer.$addFieldsthen runs$condon the grouped result to assign a category.
db.Orders.aggregate([
{
$group: {
_id: "$customerId", // group by customer
totalSpent: { $sum: "$totalAmount" } // sum all their orders
}
},
{
$addFields: {
orderCategory: {
$cond: {
if: { $gt: ["$totalSpent", 200000] },
then: "Premium",
else: "Regular"
}
}
}
}
]){ "_id": "C001", "totalSpent": 350000, "orderCategory": "Premium" }
{ "_id": "C002", "totalSpent": 85000, "orderCategory": "Regular" }Goal: Build a new collection with one document per customer containing:
customerIdtotalSpentorderCount
$groupaggregates all orders per customer —$sum: "$totalAmount"for spending,$sum: 1counts documents.$projectreshapes the output:_id: 0removes the default_idfield from output.customerId: "$_id"renames_idto a friendlier name.totalSpent: 1andorderCount: 1keep those fields.
$mergewithwhenNotMatched: 'insert'creates theCustomerAnalyticscollection (and documents) if they don't exist yet.
db.Orders.aggregate([
{
$group: {
_id: "$customerId",
totalSpent: { $sum: "$totalAmount" },
orderCount: { $sum: 1 } // count each document as 1
}
},
{
$project: {
_id: 0, // hide the default _id
customerId: "$_id", // rename _id → customerId
totalSpent: 1,
orderCount: 1
}
},
{
$merge: {
into: 'CustomerAnalytics', // target collection
on: "_id",
whenMatched: 'merge',
whenNotMatched: 'insert' // create if doesn't exist
}
}
]){ "customerId": "C001", "totalSpent": 350000, "orderCount": 12 }
{ "customerId": "C002", "totalSpent": 85000, "orderCount": 5 }Input Documents
│
▼
$match → Filter documents by condition
│
▼
$group → Collapse into groups (1 doc per unique _id)
│
▼
$addFields → Add or compute new fields per document
│
▼
$project → Reshape output (include/exclude/rename fields)
│
▼
$count → Count remaining documents → single output doc
│
▼
$merge → Write results into a collection
| Option | Value | Meaning |
|---|---|---|
into |
'CollectionName' |
Target collection |
on |
'_id' |
Field to match on |
whenMatched |
'merge' |
Merge fields into existing doc |
whenMatched |
'replace' |
Replace the entire doc |
whenNotMatched |
'insert' |
Create a new doc |
whenNotMatched |
'discard' |
Skip — do nothing |
// Object syntax
$cond: {
if: <condition>,
then: <value-if-true>,
else: <value-if-false>
}
// Array syntax (shorthand)
$cond: [ <condition>, <value-if-true>, <value-if-false> ]