Accumulators¶
Accumulators are used within the $group stage to compute values across
grouped documents. Mongo Aggro provides typed accumulator classes with
IDE autocomplete and validation.
Using Accumulators¶
With merge_accumulators() (Recommended)¶
Use typed accumulator classes for better IDE support and validation:
from mongo_aggro import Group, Sum, Avg, Max, Min, merge_accumulators
Group(
id="$category",
accumulators=merge_accumulators(
Sum(name="totalSales", field="amount"),
Avg(name="avgSale", field="amount"),
Max(name="maxSale", field="amount"),
Min(name="minSale", field="amount"),
)
)
Raw Dictionary¶
For simple cases, raw dicts work too:
Group(
id="$category",
accumulators={
"totalSales": {"$sum": "$amount"},
"avgSale": {"$avg": "$amount"},
}
)
Basic Accumulators¶
Sum¶
Sums values or counts documents.
from mongo_aggro import Sum
# Sum a field
Sum(name="total", field="amount")
# {"total": {"$sum": "$amount"}}
# Count documents
Sum(name="count", value=1)
# {"count": {"$sum": 1}}
Avg¶
Calculates the average of values.
Min / Max¶
Gets minimum or maximum values.
from mongo_aggro import Min, Max
Min(name="lowestPrice", field="price")
# {"lowestPrice": {"$min": "$price"}}
Max(name="highestPrice", field="price")
# {"highestPrice": {"$max": "$price"}}
First / Last¶
Gets the first or last value in each group.
from mongo_aggro import First, Last
First(name="firstOrder", field="orderId")
# {"firstOrder": {"$first": "$orderId"}}
Last(name="lastOrder", field="orderId")
# {"lastOrder": {"$last": "$orderId"}}
Array Accumulators¶
Push¶
Adds values to an array.
from mongo_aggro import Push
# Push field values
Push(name="items", field="itemName")
# {"items": {"$push": "$itemName"}}
# Push expressions
Push(name="orderDetails", expression={"id": "$orderId", "amount": "$total"})
# {"orderDetails": {"$push": {"id": "$orderId", "amount": "$total"}}}
AddToSet¶
Adds unique values to an array.
from mongo_aggro import AddToSet
AddToSet(name="uniqueTags", field="tag")
# {"uniqueTags": {"$addToSet": "$tag"}}
Statistical Accumulators¶
StdDevPop / StdDevSamp¶
Calculates standard deviation.
from mongo_aggro import StdDevPop, StdDevSamp
# Population standard deviation
StdDevPop(name="stdDev", field="score")
# {"stdDev": {"$stdDevPop": "$score"}}
# Sample standard deviation
StdDevSamp(name="sampleStdDev", field="score")
# {"sampleStdDev": {"$stdDevSamp": "$score"}}
Count Accumulator¶
Count_¶
Counts documents in each group.
Note
The class is named Count_ (with underscore) to avoid conflict with the Count stage.
Object Accumulators¶
MergeObjects¶
Merges documents into a single document.
from mongo_aggro import MergeObjects
MergeObjects(name="combined", field="metadata")
# {"combined": {"$mergeObjects": "$metadata"}}
N-Value Accumulators¶
TopN / BottomN¶
Gets top or bottom N values based on sort order.
from mongo_aggro import TopN, BottomN
TopN(
name="top3Products",
n=3,
sort_by={"sales": -1},
output="$productName"
)
# {"top3Products": {"$topN": {"n": 3, "sortBy": {"sales": -1}, "output": "$productName"}}}
BottomN(
name="bottom3Products",
n=3,
sort_by={"sales": -1},
output="$productName"
)
FirstN / LastN¶
Gets first or last N values.
from mongo_aggro import FirstN, LastN
FirstN(name="first5", n=5, input="$item")
# {"first5": {"$firstN": {"n": 5, "input": "$item"}}}
LastN(name="last5", n=5, input="$item")
# {"last5": {"$lastN": {"n": 5, "input": "$item"}}}
MaxN / MinN¶
Gets N maximum or minimum values.
from mongo_aggro import MaxN, MinN
MaxN(name="top3Scores", n=3, input="$score")
# {"top3Scores": {"$maxN": {"n": 3, "input": "$score"}}}
MinN(name="lowest3Scores", n=3, input="$score")
# {"lowest3Scores": {"$minN": {"n": 3, "input": "$score"}}}
Complete Example¶
from mongo_aggro import (
Pipeline, Match, Group, Sort, Limit,
Sum, Avg, Max, Min, First, Last, Push, Count_,
merge_accumulators
)
pipeline = Pipeline([
Match(query={"status": "completed", "year": 2024}),
Group(
id="$category",
accumulators=merge_accumulators(
Sum(name="totalRevenue", field="amount"),
Avg(name="avgOrderValue", field="amount"),
Max(name="largestOrder", field="amount"),
Min(name="smallestOrder", field="amount"),
First(name="firstOrderDate", field="orderDate"),
Last(name="lastOrderDate", field="orderDate"),
Push(name="allOrderIds", field="orderId"),
Count_(name="orderCount"),
)
),
Sort(fields={"totalRevenue": -1}),
Limit(count=10),
])