MongoDB $max Accumulator

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

What You’ll Learn

The $max accumulator finds the highest value in each $group bucket—ideal for top scores, peak prices, highest quantities, and range reports alongside $min.

01

Peak per group

Largest value in the bucket.

02

Simple syntax

{ $max: "$field" }

03

No $sort needed

Scans all docs in group.

04

Expressions OK

Max of computed values.

05

vs $last

Peak value vs last doc.

06

Null handling

Skips null when others exist.

Definition and Usage

$max is a MongoDB accumulator used in the $group stage. For each group, it evaluates an expression on every document and returns the maximum value found.

💡
Beginner tip

Unlike $first or $last, $max does not care about document order—it compares values across the whole group. Scores 85, 92, and 78 yield 92 whether or not you sorted first.

Use $max for leaderboard peaks, inventory high-water marks, price ceilings, and validation checks. Pair with $min for min/max ranges, or use $topN when you need the full document that achieved the peak, not just the number.

📝 Syntax

$max takes one expression inside $group:

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

Syntax Rules

  • Stage — primary use as accumulator in $group (also $bucket, windows).
  • Expression — field path like "$score" or a formula like { $multiply: ["$price", "$quantity"] }.
  • Output — the highest value found, or null if no usable values exist.
  • Comparison — uses BSON comparison order; mixed types compare by type ranking, not just numeric magnitude.
  • Null / missing — ignored when at least one non-null value exists in the group.
  • _id: null — one global maximum across all documents.
mongosh
db.students.aggregate([
  {
    $group: {
      _id: null,
      maxScore: { $max: "$score" }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage$group accumulator
Syntax{ $max: <expression> }
Needs $sort?No—scans entire group
Empty / all nullReturns null
vs $min$max = highest; $min = lowest
vs $last$max = peak anywhere; $last = value on last doc
Global max
{ _id: null,
  max: { $max: "$score" } }

One peak for all docs

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

Max per class

Expression
{ $max: {
  $multiply: ["$price", "$qty"]
} }

Max of computed total

Min + max
low:  { $min: "$score" }
high: { $max: "$score" }

Range in one $group

🧰 Parameters

$max accepts one expression inside $group:

expression Required

Value compared for each document in the group. Can be a field path or any expression MongoDB can compare using BSON ordering rules.

{ $max: "$salary" }
{ $max: { $add: ["$base", "$bonus"] } }
_id Group key

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

_id: "$item"
return type Value | null

Returns the winning value’s type (number, date, string, etc.). With mixed types, BSON comparison order determines the result type.

92
null / missing Important

If some documents have values, null and missing fields are skipped. If all are null or missing, result is null.

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

Examples Gallery

Student scores and sales data—find global and per-group maximums, use expressions, and compare with related operators.

📚 Getting Started

Insert sample student scores and find the highest score overall.

Example 1 — Sample students collection

mongosh
db.students.insertMany([
  { name: "Alice",   class: "10A", score: 85 },
  { name: "Bob",     class: "10A", score: 92 },
  { name: "Charlie", class: "10B", score: 78 },
  { name: "Diana",   class: "10B", score: 88 },
  { name: "Eve",     class: "10A", score: 90 }
]);

How It Works

Five students across two classes—the global max is Bob’s 92; class 10A max is also 92.

Example 2 — Highest score overall

mongosh
db.students.aggregate([
  {
    $group: {
      _id: null,
      maxScore: { $max: "$score" }
    }
  }
]);

/* Result:
{ _id: null, maxScore: 92 }
   — Bob has the highest score */
*/

How It Works

_id: null groups every document together. $max compares all score values and returns 92.

📈 Practical Patterns

Break maximums down by category, compute on expressions, and compare operators.

Example 3 — Max score per class (with $min)

mongosh
db.students.aggregate([
  {
    $group: {
      _id: "$class",
      minScore: { $min: "$score" },
      maxScore: { $max: "$score" }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Result:
[
  { _id: "10A", minScore: 85, maxScore: 92 },
  { _id: "10B", minScore: 78, maxScore: 88 }
]
*/

How It Works

Grouping by class gives independent min/max ranges per section—common for grade spread reports.

Example 4 — Max line total per product (expression)

Find the highest price × quantity per item:

mongosh
db.sales.insertMany([
  { item: "abc", price: 10, quantity: 2 },
  { item: "jkl", price: 20, quantity: 1 },
  { item: "xyz", price: 5,  quantity: 5 },
  { item: "abc", price: 10, quantity: 10 },
  { item: "xyz", price: 5,  quantity: 10 }
]);

db.sales.aggregate([
  {
    $group: {
      _id: "$item",
      maxTotal: {
        $max: { $multiply: ["$price", "$quantity"] }
      },
      maxQty: { $max: "$quantity" }
    }
  },
  { $sort: { _id: 1 } }
]);

/* abc → maxTotal: 100 (10×10), maxQty: 10
   jkl → maxTotal: 20,  maxQty: 1
   xyz → maxTotal: 50,  maxQty: 10 */
*/

How It Works

$max accepts any expression—not just a field path. MongoDB evaluates $multiply per document, then picks the largest result.

Example 5 — $max vs $last

Peak value is not always on the most recent document:

mongosh
db.students.aggregate([
  { $sort: { class: 1, score: 1 } },
  {
    $group: {
      _id: "$class",
      maxScore:      { $max: "$score" },
      lastDocScore:  { $last: "$score" }
    }
  }
]);

/* 10A (sorted asc by score: 85, 90, 92):
   maxScore: 92
   lastDocScore: 92 — same here

   If Eve(95) were last by date but Bob(92) had max:
   maxScore → 95 or 92 depending on data;
   lastDocScore → score on final sorted doc */
*/

How It Works

Use $max when you need the peak. Use $last when you need the value tied to the most recent (sorted) record—they answer different questions.

🧠 How $max Works

1

Documents bucketed

$group assigns each document to a bucket via _id.

Group
2

Expression evaluated

For each document, MongoDB computes the $max expression (field or formula).

Evaluate
3

Values compared

MongoDB tracks the running maximum using BSON comparison rules across all documents in the bucket.

Compare
=

Maximum returned

One peak value per group—or null if no comparable values exist.

📝 Notes

  • $max does not require $sort—it scans the entire group.
  • Returns null when every document has null or missing values for the expression.
  • With mixed BSON types, comparison follows type order—not intuitive numeric max across strings and numbers.
  • Tied equal values: MongoDB may return any of the ties—no guaranteed pick.
  • In $group, array fields are compared as whole arrays, not element-by-element.
  • Previous topic: $lastN. Next: $maxN.

Conclusion

$max is the go-to accumulator for peak values inside $group. It is simple, order-independent, and works on field paths or expressions like $multiply.

Pair with $min for ranges, use $top when you need the full winning document, or explore $maxN for the N largest values per group.

💡 Best Practices

✅ Do

  • Use $max + $min in one $group for score/price ranges
  • Filter with $match before $group to max only relevant documents
  • Use expressions when the peak of a computed value matters (line totals, durations)
  • Validate numeric types with $match: { field: { $type: "number" } } when data is messy
  • Use $top or $bottom when you need identifying fields from the peak record

❌ Don’t

  • Confuse $max with $last (peak vs last document’s value)
  • Assume $max returns the student name—it returns the maximum value only
  • Compare mixed types without understanding BSON type ordering
  • Expect $max to traverse into array elements inside $group
  • Use $max when you need N largest values—use $maxN instead

Key Takeaways

Knowledge Unlocked

Five things to remember about $max

Use these points when finding peak values inside $group.

5
Core concepts
📝 02

Simple syntax

{ $max: "$field" }

Syntax
📊 03

No $sort

Scans whole group.

Pattern
🔄 04

vs $last

Peak vs trailing doc.

Compare
💲 05

+ $min

Min/max ranges.

Pair

❓ Frequently Asked Questions

$max returns the highest value of an expression across all documents in each $group bucket. It scans every document in the group and picks the maximum—no $sort required.
Inside $group: { maxScore: { $max: "$score" } }. It also works as an expression in $project, $addFields, and window stages—but this tutorial focuses on the $group accumulator.
Grouping with _id: null puts all documents into one bucket, so $max returns a single overall maximum for the entire filtered collection.
If some documents have values and others are null or missing, $max ignores the null/missing ones. If every document lacks a usable value, $max returns null.
$max finds the largest value anywhere in the group. $last returns a field from the last document in pipeline order—they differ when the peak value is not on the last document.
$max returns the highest value; $min returns the lowest. Use both in the same $group for range summaries (min score and max score per class).
Did you know?

$max and $min use BSON comparison order, so dates, strings, and numbers compare by type rules—not just numeric magnitude. For the N largest numbers specifically, MongoDB 5.2+ offers $maxN. See the official $max docs.

Continue the Accumulators Series

Find peak values with $max, then learn $maxN for the N largest values per group.

Next: $maxN →

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