MongoDB $bottom Accumulator

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

What Is $bottom?

$bottom is a MongoDB accumulator for the $group stage (MongoDB 5.2+). For each group it ranks documents with sortBy, then returns one document—the one at the bottom of that order.

Remember
$bottom = last document after sortBy (per group)

sortBy → rank inside the group (same rules as $sort)
output → what to return ($$ROOT or selected fields)

sortBy: { score: -1 } → descending; last = lowest score
vs $min → $min returns a number; $bottom returns a document
UsePrefer
Whole lowest-ranked record$bottom
Only the minimum field value$min
N lowest-ranked documents$bottomN

How to Use $bottom in MongoDB

Two keys drive every call: output and sortBy.

  1. Put $bottom inside $group on an output field.
  2. Set sortBy like $sort (1 ascending, -1 descending).
  3. Set output to "$$ROOT" or a projection object.
  4. Choose _id for the group key (class, store, or null).
KeyRequired?Role
sortByYesRanking inside the group (same shape as $sort)
outputYes"$$ROOT" or { name: "$student", … }
$group._idYesGroup key ("$class", null, …)

Pseudocode

Pseudocode
for each group:
    ranked = sort(documents, sortBy)   // e.g. score descending
    winner = last document in ranked   // the "bottom"
    emit { _id: groupKey, field: project(winner, output) }

Cheat Sheet

Keep these facts handy while picking the bottom-ranked document.

TopicDetail
Stage$group only (as an accumulator)
Required keysoutput, sortBy
ReturnsOne object per group (not an array)
Lowest scoresortBy: { score: -1 } (last after descending)
VersionMongoDB 5.2+
Sample checkclass A: Sam 90, Ana 70, Lee 85 → bottom is Ana (70)

Live Preview

Watch which student wins with sortBy: { score: -1 }. Sample: A/Sam 90, A/Ana 70, A/Lee 85, B/Mia 60, B/Omar 95.

Simulates descending score sort; the last document is the $bottom winner (lowest score).

Result
class A sorted by score ↓: Sam 90, Lee 85, Ana 70
  → bottom = Ana (70)
class B sorted by score ↓: Omar 95, Mia 60
  → bottom = Mia (60)

[
  { _id: "A", lowest: { name: "Ana", score: 70 } },
  { _id: "B", lowest: { name: "Mia", score: 60 } }
]

Worked Walkthrough — Lowest Score per Class

Five students, two classes. Sort scores descending; $bottom takes the last row—the lowest score.

Calculation
Documents:
  { class: "A", student: "Sam",  score: 90 }
  { class: "A", student: "Ana",  score: 70 }
  { class: "A", student: "Lee",  score: 85 }
  { class: "B", student: "Mia",  score: 60 }
  { class: "B", student: "Omar", score: 95 }

sortBy: { score: -1 }  // descending

class "A" ranked: Sam(90), Lee(85), Ana(70)
  bottom (last) → Ana

class "B" ranked: Omar(95), Mia(60)
  bottom (last) → Mia

Output:
  { _id: "A", lowest: { name: "Ana", score: 70 } }
  { _id: "B", lowest: { name: "Mia", score: 60 } }

MongoDB Examples

We use a tiny scores collection. First we return the lowest scorer per class. Then we return the full document with $$ROOT. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine five students. Each document has a class, student name, and score.

mongosh
db.scores.insertMany([
  { class: "A", student: "Sam", score: 90 },
  { class: "A", student: "Ana", score: 70 },
  { class: "A", student: "Lee", score: 85 },
  { class: "B", student: "Mia", score: 60 },
  { class: "B", student: "Omar", score: 95 }
]);

How the Data Is Stored in MongoDB

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

mongosh
db.scores.find()

Read each document like this:

Field in MongoDBMeaningExample
classClass / group name"A"
studentStudent name"Ana"
scoreTest score70
Picture
Class A scores: Sam 90, Ana 70, Lee 85
Class B scores: Mia 60, Omar 95

Next: $bottom finds the lowest-ranked student per class.

How It Works

  1. Insert once. The sample command adds 5 documents to scores.
  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 $bottom in the next examples.

With sortBy: { score: -1 }, class A’s bottom is Ana (70); class B’s bottom is Mia (60).

Example 2 — Lowest Scorer per Class

Goal: for each class, return the student with the lowest score—name and score only. Descending sortBy puts the smallest score last, so $bottom picks it.

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      lowest: {
        $bottom: {
          output: { name: "$student", score: "$score" },
          // descending → last document = lowest score
          sortBy: { score: -1 }
        }
      }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Split by class. _id: "$class" makes groups "A" and "B".
  2. Rank high to low. sortBy: { score: -1 } orders each group from highest score to lowest.
  3. Pick the last row. That last document is the lowest score (Ana 70, Mia 60)—exactly what official MongoDB examples do.
  4. Shape the result. output keeps only name and score—not the full source document.
  5. Need only the number? Use { $min: "$score" } when you do not need the student name.

Example 3 — Full Document with $$ROOT

Goal: return the entire bottom-ranked document. output: "$$ROOT" keeps every field from the winning row.

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      lowestDoc: {
        $bottom: {
          output: "$$ROOT",
          sortBy: { score: -1 }
        }
      }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Same ranking. sortBy: { score: -1 } still picks Ana and Mia as the last (lowest) rows.
  2. $$ROOT means the whole doc. You get class, student, score, and the original _id.
  3. Projection vs root. Example 2 is lighter for APIs; Example 3 is handy when you need every field later.
  4. Need several lows? Switch to $bottomN with an n value.

Edge Cases & Pitfalls

Check these before shipping a bottom-ranked report.

sortBy

Bottom = last after sortBy

For the lowest score use { score: -1 } so the smallest value is last. With { score: 1 }, $bottom returns the highest score instead.

ties

Tied sort keys are ambiguous

If two students share the same score, add a second key (e.g. student: 1) so the winner is predictable.

min

Do not use $bottom for a bare minimum

When you only need the number, $min is simpler and clearer than projecting a whole document.

version

Requires MongoDB 5.2+

Older servers lack $bottom. Use $sort plus $group with $first / $last as a fallback.

Performance Notes

ApproachCostBest for
$bottomTracks one winner per group while scanningOne extreme document with fields
$minTracks one scalarMinimum value only
$bottomNTracks N winnersTop/bottom lists of size N

Prefer $min when a single number is enough. Filter early with $match so fewer documents enter each group. Keep sortBy fields indexed only when you sort before grouping in a larger pipeline.

Key Takeaways

  • Role: one lowest-ranked document per $group.
  • Keys: sortBy ranks; output shapes the result.
  • vs $min: document vs bare minimum value.
  • N results: use $bottomN when you need more than one.

One line: $bottom returns the document at the end of your in-group sort—ideal when you need fields from the extreme row.

Frequently Asked Questions

$bottom returns one document per $group—the document ranked last according to the sortBy order you give. Use it when you need the whole record (name, score, date), not just a single field value.
Inside $group: { lowest: { $bottom: { output: "$$ROOT", sortBy: { score: -1 } } } }. Both output and sortBy are required. Use score: -1 when you want the lowest score.
$min returns the smallest value of one field (for example 72). $bottom returns a document—the student or order that sits at the bottom of your sort order.
$bottom returns exactly one bottom-ranked document. $bottomN returns N bottom documents as an array. Use $bottom when you only need the single lowest record.
$bottom was added in MongoDB 5.2 with the $top / $bottom family. On older servers, use $sort plus $first / $last patterns instead.
sortBy ranks documents inside each group—same rules as $sort. $bottom returns the last document in that order. For the lowest score, use { score: -1 } (descending) so the smallest value is last.

Next: $bottomN

Return the N lowest-ranked documents in each group.

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