MongoDB $max Accumulator

Beginner
5 min read
Updated: Oct 2026
3 examples
Live preview

What Is $max?

$max is a MongoDB accumulator for the $group stage. For each group it returns the highest value of an expression across all documents in that bucket. No $sort is required.

Remember
$max = highest value per group

scan every document in the group
compare values → keep the larger one
null / missing → ignored when other values exist

vs $min → lowest value
vs $last → value from last doc (order-based, not peak)
UsePrefer
Highest amount, score, or date$max
Lowest value in the same group$min
Field from the last document after sort$last

How to Use $max in MongoDB

Pass one field (or expression) inside $group.

  1. Put $max inside $group on an output field.
  2. Pass a field path (e.g. "$amount") or any comparable expression.
  3. Set _id to the group key, or null for one overall maximum.
  4. Optionally $match first so you maximize only the rows you care about.
PieceRequired?Role
$group._idYesGroup key ("$category", null, …)
$maxYesExpression to maximize
ExpressionYesUsually "$field"; may be computed

Pseudocode

Pseudocode
for each group:
    best = null
    for each document in group:
        value = evaluate(expression)
        if value is comparable:
            if best is null or value > best:
                best = value
    emit { _id: groupKey, field: best }

Cheat Sheet

Keep these facts handy while writing a maximum rollup.

TopicDetail
Stage$group accumulator (also usable on arrays in $project)
Syntax{ $max: "$field" }
Needs $sort?No — compares all values in the group
null / missingIgnored when other values exist
Empty groupReturns null when no comparable values
Sample checkfood 100, 150, 50 → max 150

Live Preview

Watch the running maximum update. Sample collection: food 100, food 150, travel 200, food 50.

Simulates keeping the larger amount as each document is seen (same idea as the mongosh examples below).

Result
+ 100 (food) → max 100
+ 150 (food) → max 150
+ 200 (travel) → max 200
+ 50 (food) → max 200

{ _id: null, maxAmount: 200 }

Worked Walkthrough — Overall Maximum

Same four purchases as the examples. The peak amount across all docs is 200.

Calculation
Documents:
  { amount: 100, category: "food" }
  { amount: 150, category: "food" }
  { amount: 200, category: "travel" }
  { amount:  50, category: "food" }

Running max:
  100 → 100
  max(100, 150) → 150
  max(150, 200) → 200
  max(200,  50) → 200

Food only:  max(100, 150, 50) = 150
Travel only: max(200) = 200

Output (all docs, _id: null):
  { _id: null, maxAmount: 200 }

MongoDB Examples

We use a tiny shopping list of four purchases. First we find the overall maximum. Then we find the maximum per category. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine four receipts in a transactions collection. Each document has an amount and a category.

mongosh
db.transactions.insertMany([
  { amount: 100, category: "food" },
  { amount: 150, category: "food" },
  { amount: 200, category: "travel" },
  { amount: 50, category: "food" }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps 4 documents in transactions. Run find() to see them:

mongosh
db.transactions.find()

Read each document like this:

Field in MongoDBMeaningExample
amountMoney spent on this purchase200
categoryWhat the purchase was for"travel"
Picture
Amounts: 100, 150, 200, 50

Next: $max finds the largest → 200

How It Works

  1. Insert once. The sample command adds 4 documents to transactions.
  2. MongoDB stores fields as written. Each document keeps the same field names and values you inserted.
  3. find() shows the same shape. What you inserted is what you get back—ready for $max in the next examples.

Quick check: overall max is 200; food max is 150; travel max is 200.

Example 2 — Overall Maximum

Goal: one highest amount for the whole collection. _id: null means “put every document in one big group.”

mongosh
db.transactions.aggregate([
  {
    $group: {
      // null = one group for the whole collection
      _id: null,
      maxAmount: { $max: "$amount" }
    }
  }
]);

How It Works

  1. One bucket. _id: null groups every document together.
  2. Read each amount. $max: "$amount" pulls the numeric field from each receipt.
  3. Keep the larger value. After 100 and 150 the max is 150; after 200 it becomes 200; 50 does not change it.
  4. No sort needed. Unlike $last, $max compares all values regardless of document order.
  5. Need several top values? Use $maxN for an array of the largest N amounts.

Example 3 — Maximum per Category

Goal: highest spend for food and for travel. _id: "$category" makes a separate group for each category value.

CategoryAmountsMaximum
food100, 150, 50150
travel200200
mongosh
db.transactions.aggregate([
  {
    $group: {
      // One group per category value ("food", "travel", ...)
      _id: "$category",
      maxAmount: { $max: "$amount" }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Split into buckets. _id: "$category" creates separate groups for food and travel.
  2. Maximize inside each bucket. Food: max(100, 150, 50) = 150. Travel: 200.
  3. Sort for stable reading. $sort orders the group keys alphabetically.
  4. Pair with $min for a range. Add { $min: "$amount" } in the same $group to get low and high together.

Edge Cases & Pitfalls

Check these before shipping a maximum report.

null

Null and missing are skipped

They do not win the comparison when other values exist. All-null groups return null.

$last

Do not confuse with $last

$max answers “what is the largest value?” $last answers “what is on the last document?”

types

Comparison uses BSON order

Mixed types compare by BSON type ranking. Prefer a single numeric (or date) type for clear results.

doc

$max returns a value, not a document

To return the whole document that holds the peak, use $top with sortBy instead.

Performance Notes

ApproachCostBest for
$maxNative, one pass per groupSingle highest value
$maxNKeeps N largest valuesTop-N amounts as an array
$sort + $lastSort costWhen you need a field from the last-sorted doc, not the peak

Prefer native $max over sorting just to find a peak. Filter early with $match so fewer documents enter the group.

Key Takeaways

  • Role: highest value inside each $group bucket.
  • Order: no $sort needed—compares all values.
  • Nulls: ignored when other values exist; all-null → null.
  • vs $last: peak value vs field from the last document.

One line: $max is the built-in peak finder for each $group bucket—scan, compare, keep the largest.

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 as an accumulator, for example { maxAmount: { $max: "$amount" } }. You can also use $max on arrays in $project, but this page focuses on the $group form.
Grouping with _id: null puts every document in one bucket, so $max returns a single overall maximum for the whole input.
Null and missing values are ignored when other comparable values exist. If every value in a group is null or missing, $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 is not on that last document.
$max returns the highest value; $min returns the lowest. Use both in the same $group for range summaries.

Next: $maxN

Return the N largest values in each group as an array.

$maxN tutorial →

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.

9 people found this page helpful