MongoDB $avg Accumulator

Beginner
⏱️ 8 min read
📚 Updated: Jul 2026
🎯 5 Examples
Aggregation

What You’ll Learn

The $avg accumulator computes the arithmetic mean of numeric values while MongoDB groups documents. It is one of the most common tools for dashboards, grades, and KPI reports.

01

Mean per group

Sum ÷ count of numeric values.

02

$group syntax

Accumulator with field or expression.

03

Overall average

Use _id: null for one global mean.

04

Per category

Average salary by department, etc.

05

Null handling

Missing values skipped automatically.

06

vs $sum

Totals vs averages in reports.

Definition and Usage

$avg is a MongoDB accumulator used in the $group stage. For each group, it evaluates an expression on every document, keeps only numeric values, adds them up, and divides by how many numeric values were counted.

💡
Beginner tip

Scores 85, 75, and 90 average to (85 + 75 + 90) / 3 = 83.33.... MongoDB performs that math for you inside $group—no manual $sum and $count required unless you need both numbers separately.

Use $avg for exam scores, order amounts, response times, ratings, and any metric where the typical value matters more than the total. Filter with $match first to average only relevant documents.

📝 Syntax

$avg takes one expression inside $group:

mongosh
{
  $group: {
    _id: <expression>,
    <outputField>: { $avg: <expression> }
  }
}

Syntax Rules

  • Stage — accumulator in $group (primary use in this tutorial).
  • Expression — field path like "$score" or a numeric formula.
  • Output — a number (double) or null if no numeric values in the group.
  • Ignored values — non-numeric types, null, and missing fields are excluded from mean calculation.
  • _id: null — groups all documents together for one overall average.
mongosh
db.scores.aggregate([
  {
    $group: {
      _id: null,
      averageScore: { $avg: "$score" }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage$group accumulator
Syntax{ $avg: <expression> }
Formulasum of numeric values ÷ count of numeric values
Empty groupReturns null
vs $sum$sum = total; $avg = total ÷ count
Round result$project with $round after $group
Global avg
{ _id: null,
  avg: { $avg: "$score" } }

One mean for all docs

By category
{ _id: "$class",
  avg: { $avg: "$score" } }

Mean per class

Expression
{ $avg: {
  $add: ["$base", "$bonus"]
} }

Average of computed value

Round
{ $round: [
  "$averageScore", 2
] }

Two decimal places

🧰 Parameters

$avg accepts one expression inside $group:

expression Required

Value to include in the mean for each document in the group. Must evaluate to a number (or be ignorable) for each input document.

{ $avg: "$salary" }
_id Group key

Defines buckets. Use a field path for per-category averages, compound keys for multi-field grouping, or null for a single global bucket.

_id: "$department"
return type Number | null

Result is typically a double-precision float. Long and Decimal128 inputs are supported; output may be Double or Decimal128 depending on input types.

83.33333333333333
ignored inputs Important

Strings, booleans, arrays, objects, null, and missing fields do not contribute to sum or count. They are silently skipped.

$match: { score: { $type: "number" } }

Examples Gallery

Student scores sample data, then calculate overall and per-class averages with optional rounding.

📚 Getting Started

Insert sample scores and compute the mean across all students.

Example 1 — Sample scores collection

Documents with student, class, and score:

mongosh
db.scores.insertMany([
  { student: "Alice",   class: "10A", score: 85 },
  { student: "Bob",     class: "10A", score: 75 },
  { student: "Charlie", class: "10B", score: 90 },
  { student: "Diana",   class: "10B", score: 80 },
  { student: "Eve",     class: "10A", score: 95 }
]);

How It Works

Three students in class 10A and two in 10B give us enough data to show both a global average and per-class averages.

Example 2 — Overall average score

Group all documents with _id: null and average score:

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: null,
      averageScore: { $avg: "$score" }
    }
  }
]);

/* Result:
{ _id: null, averageScore: 85 }
   (85 + 75 + 90 + 80 + 95) / 5 = 85
*/

How It Works

_id: null means “one group containing every document.” The old tutorial example with scores 85, 75, 90 (average 83.33) uses the same pattern with three documents.

📈 Practical Patterns

Break averages down by category, filter first, and format output.

Example 3 — Average score per class

Group by class to compare sections:

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      averageScore: { $avg: "$score" },
      studentCount: { $sum: 1 }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Result:
[
  { _id: "10A", averageScore: 85, studentCount: 3 },
  { _id: "10B", averageScore: 85, studentCount: 2 }
]
*/

How It Works

Pairing $avg with $sum: 1 (document count) helps readers understand whether a high or low average is based on many records or just a few.

Example 4 — Average after $match filter

Only average scores for class 10A:

mongosh
db.scores.aggregate([
  { $match: { class: "10A" } },
  {
    $group: {
      _id: null,
      averageScore: { $avg: "$score" }
    }
  }
]);

// (85 + 75 + 95) / 3 = 85

How It Works

Put $match before $group so MongoDB averages fewer documents—often faster when supported by an index on the filter field.

Example 5 — Round the average for display

Long floating-point means are hard to read; round in $project:

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: null,
      averageScore: { $avg: "$score" }
    }
  },
  {
    $project: {
      _id: 0,
      averageScore: { $round: ["$averageScore", 2] }
    }
  }
]);

// Three scores 85, 75, 90 → raw 83.333… → rounded 83.33

How It Works

Keep full precision inside $group if downstream math needs it; round only in the final presentation stage.

🧠 How $avg Works

1

Documents enter $group

MongoDB assigns each document to a bucket based on the _id expression.

Group
2

Evaluate expression

For each document, compute the $avg expression. Non-numeric results are skipped.

Eval
3

Track sum and count

MongoDB internally accumulates the running total and how many numeric values contributed.

Accumulate
=

Mean returned

Each group outputs sum ÷ count as the $avg field value—or null if count is zero.

📝 Notes

  • $avg is an accumulator in $group—not a query filter operator.
  • Null and missing field values are ignored and do not reduce the average to zero.
  • If every value in a group is non-numeric, $avg returns null.
  • Results may show long decimals (e.g. 83.33333333333333)—use $round for display.
  • For weighted averages, compute with $sum and custom fields rather than plain $avg.
  • Previous topic: $addToSet. Next: $bottom.

Conclusion

$avg is the go-to MongoDB accumulator for arithmetic means: overall KPIs with _id: null, breakdowns by department or product line, and filtered reports after $match.

Remember it skips non-numeric values, pair it with counts when context matters, and round only at the end. For totals instead of means, use $sum; for spread, explore $stdDevPop and $stdDevSamp.

💡 Best Practices

✅ Do

  • Place $match before $group to average the right subset
  • Include document count ($sum: 1) alongside averages in reports
  • Use $round or $trunc in $project for UI-friendly numbers
  • Validate that score/amount fields are stored as numbers, not strings
  • Index fields used in $match before heavy grouping

❌ Don’t

  • Expect string numbers like "85" to be averaged (they are ignored)
  • Assume null scores count as zero—they are excluded from the mean
  • Use $avg when you need a total—use $sum instead
  • Compare averages across groups with very different counts without noting sample size
  • Forget that _id: null still outputs _id: null in the result document

Key Takeaways

Knowledge Unlocked

Five things to remember about $avg

Use these points whenever you compute means in aggregation pipelines.

5
Core concepts
📦 02

$group

Accumulator context.

Syntax
🎯 03

_id: null

Global average.

Pattern
04

Skips null

Non-numbers ignored.

Gotcha
📐 05

$round

Format for display.

Tip

❓ Frequently Asked Questions

$avg calculates the arithmetic mean of numeric values in each $group bucket. It adds the numbers and divides by the count of numeric inputs, ignoring non-numeric values.
Inside the $group stage: { avgScore: { $avg: "$score" } }. You can also use the $avg expression operator on arrays in $project and $addFields, but this tutorial focuses on the $group accumulator.
Grouping with _id: null puts all documents into one bucket, so $avg returns a single overall average for the entire filtered collection.
Null and missing values are ignored—they do not count toward the sum or the divisor. If no numeric values exist in a group, $avg returns null.
$sum totals numeric values. $avg divides that total by the number of numeric values counted. Use $avg for means (average salary); use $sum for totals (total revenue).
Yes. Pass any numeric expression: { $avg: { $add: ["$base", "$bonus"] } } averages base plus bonus per document in the group.
Did you know?

You can replicate $avg manually with $sum and $sum: 1 plus a $project division stage—but $avg is clearer and handles ignored non-numeric values for you. See the official $avg aggregation docs.

Continue the Accumulators Series

Compute means with $avg, then learn how $bottom picks the lowest-ranked document per group.

Next: $bottom →

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.

5 people found this page helpful