MongoDB $min Accumulator

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

What Is $min?

$min is a MongoDB accumulator for the $group stage. For each group it returns the lowest value of an expression—no $sort required.

Remember
$min = lowest value per group

compare every non-null input → keep the smallest
null / missing → ignored (unless all are null → null)

vs $max  → highest value
vs $minN → N smallest values as an array
vs $bottom → whole document, not a bare value
UsePrefer
Lowest price, score, amount$min
Highest value$max
N smallest values$minN
Whole lowest-ranked document$bottom

How to Use $min in MongoDB

Pass one expression inside $group.

  1. Put $min inside $group on an output field.
  2. Pass a field path (e.g. "$amount") or a numeric expression.
  3. Set _id to the group key, or null for one overall minimum.
  4. Optionally $match first so you compare only the rows you care about.
PieceRequired?Role
$group._idYesGroup key ("$category", null, …)
$minYesExpression whose lowest value to keep
ExpressionYesUsually "$field"; may be computed

Pseudocode

Pseudocode
for each group:
    minVal = unset
    for each document in group:
        value = evaluate(expression)
        if value is not null:
            if minVal is unset or value < minVal:
                minVal = value
    emit { _id: groupKey, field: minVal ?? null }

Cheat Sheet

Keep these facts handy while finding a minimum.

TopicDetail
Stage$group accumulator (also usable in $project)
Syntax{ $min: "$field" }
ReturnsOne lowest value per group
null / missingIgnored; all null → null
$sort needed?No—$min compares itself
Sample checkamounts 100, 150, 200, 50 → min 50

Live Preview

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

Simulates keeping the lowest amount seen so far (same idea as the mongosh examples below).

Result
see 100 (food) → min 100
see 150 (food) → min 100
see 200 (travel) → min 100
see 50 (food) → min 50

{ _id: null, minAmount: 50 }

Worked Walkthrough — Overall Minimum

Same four purchases as the examples. The lowest amount across all docs is 50.

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

All docs (_id: null):
  min(100, 150, 200, 50) = 50

Food only:
  min(100, 150, 50) = 50

Travel only:
  min(200) = 200

Output (all docs):
  { _id: null, minAmount: 50 }

MongoDB Examples

We use a tiny shopping list of four purchases. First we find the overall minimum amount. Then we find the minimum 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 purchase50
categoryWhat the purchase was for"food"
Picture
Amounts: 100, 150, 200, 50

Next: $min finds the smallest → 50

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 $min in the next examples.

Quick math: overall min is 50; food min is 50; travel min is 200.

Example 2 — Overall Minimum

Goal: one lowest 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,
      minAmount: { $min: "$amount" }
    }
  }
]);

How It Works

  1. One bucket. _id: null groups every document together.
  2. Read each amount. $min: "$amount" looks at every receipt.
  3. Keep the smallest. After 100, 150, 200, and 50, the winner is 50.
  4. No sort needed. $min compares values itself—you do not need a $sort stage.
  5. Need the peak instead? Swap in { $max: "$amount" }.

Example 3 — Minimum per Category

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

CategoryAmountsMinimum
food100, 150, 5050
travel200200
mongosh
db.transactions.aggregate([
  {
    $group: {
      // One group per category value ("food", "travel", ...)
      _id: "$category",
      minAmount: { $min: "$amount" }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Split into buckets. _id: "$category" creates separate groups for food and travel.
  2. Minimum inside each bucket. Food: min(100, 150, 50) = 50. Travel: 200.
  3. Sort for stable reading. $sort orders the group keys alphabetically.
  4. Same operator, different key. Only _id changed from Example 2—$min still picks the lowest value.
  5. Need several lows? Use $minN for an array of the N smallest amounts.

Edge Cases & Pitfalls

Check these before shipping a minimum report.

null

Null and missing are skipped

They do not become zero. Only non-null values compete. If every value is null, the result is null.

types

Mixed types use BSON order

Numbers and strings compare by type rules, not “numeric sense.” Keep the field type consistent when you can.

document

$min is a value, not a document

You get 50, not the whole receipt. Need the full row? Use $bottom with sortBy.

ties

Equal minimums are interchangeable

If two values compare equal, $min may return either. That matters mainly with collations on strings.

Performance Notes

ApproachCostBest for
$minNative, tracks one value per groupSingle lowest value
$minNTracks up to n valuesBottom-N lists
$sort + $firstFull sort costAvoid when a plain $min is enough

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

Key Takeaways

  • Role: lowest value inside $group.
  • Nulls: skipped; all null returns null.
  • vs $max / $minN: peak vs floor vs N smallest.
  • Document needed? Use $bottom, not $min.

One line: $min is the built-in floor for each $group bucket—one lowest value, nulls ignored.

Frequently Asked Questions

$min returns the lowest value of an expression across all documents in each $group bucket. It compares every value in the group and picks the minimum—no $sort required.
Inside $group: { minAmount: { $min: "$amount" } }. It also works as an expression in $project and $addFields, but this page focuses on the $group accumulator.
Grouping with _id: null puts every document in one bucket, so $min returns a single overall minimum for the whole input.
If some documents have values and others are null or missing, $min ignores the null/missing ones. If every document lacks a usable value, $min returns null.
$min returns the lowest value; $max returns the highest. Use both in the same $group for range summaries (min and max price per category).
$min returns one lowest value. $minN returns an array of the N smallest values. Use $min for a single floor; use $minN for a short bottom list.

Next: $minN

Return the N smallest values in each group.

$minN 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