MongoDB $top Accumulator

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

What You’ll Learn

The $top accumulator picks the single highest-ranked document in each $group bucket using a sortBy specification—ideal for “best score,” “latest order,” or “highest price” reports.

01

One doc per group

Full record at top of sort.

02

sortBy required

Defines what “top” means.

03

output shape

$$ROOT or selected fields.

04

vs $max

Value only vs whole document.

05

vs $topN

One record vs N records.

06

MongoDB 5.2+

Part of $top/$bottom family.

Definition and Usage

$top is a MongoDB accumulator used in the $group stage. It sorts documents within each group according to sortBy, then returns the document at the top of that ordering—the first document in the sorted list.

💡
Beginner tip

With sortBy: { score: -1 }, descending order puts the highest score at the top—so $top returns the student with the best score in each class. Use date: -1 when “top” should mean the most recent record.

Choose $top when you need identifying fields (name, id, date) from the winning record. Use $max when you only need the numeric maximum. Need multiple top-ranked rows? Use $topN.

📝 Syntax

$top requires an object with output and sortBy:

mongosh
{
  $group: {
    _id: <expression>,
    <field>: {
      $top: {
        output: <expression> | { <field>: <expression>, ... },
        sortBy: { <field>: <1 | -1>, ... }
      }
    }
  }
}

Syntax Rules

  • output — what to return: "$$ROOT" for the full document, or a projection object.
  • sortBy — required; same format as $sort (1 = ascending, -1 = descending).
  • One document — unlike $topN, result is a single object per group, not an array.
  • Ties — when sort keys tie, MongoDB picks one of the tied documents (do not rely on tie order without extra sort fields).
  • Version — available in MongoDB 5.2 and later.
mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      topScorer: {
        $top: {
          output: { name: "$student", score: "$score" },
          sortBy: { score: -1 }
        }
      }
    }
  }
]);

⚡ Quick Reference

QuestionAnswer
Stage$group accumulator
Required keysoutput, sortBy
ReturnsOne document (or projected object) per group
Highest score patternsortBy: { score: -1 }
Full documentoutput: "$$ROOT"
MongoDB version5.2+
Highest score
sortBy: { score: -1 }

Descending → max at top

Latest date
sortBy: { date: -1 }

Most recent at top

Full doc
output: "$$ROOT"

Entire source document

Tie-break
sortBy: {
  score: -1,
  student: 1
}

Stable ordering

🧰 Parameters

The $top object has two required properties:

output Required

Expression or document defining what the accumulator returns. Use "$$ROOT" for the full input document, or build a sub-object with field projections.

output: "$$ROOT"
output: { id: "$_id", score: "$score" }
sortBy Required

Sort specification applied within each group before picking the top document. Mirrors $sort syntax with 1 (asc) and -1 (desc).

sortBy: { score: -1 }
sortBy: { date: -1, amount: -1 }
_id Group key

Standard $group bucket key—e.g. "$class" for per-class top scorers.

_id: "$department"
empty group Edge case

If no documents fall in a group, that group is not emitted. Pipelines with only empty buckets return an empty result set.

$match before $group

Examples Gallery

Student scores by class—find the top scorer per section, return full documents, and compare with $max.

📚 Getting Started

Sample scores and the core $top grouping pattern.

Example 1 — Sample scores collection

mongosh
db.scores.insertMany([
  { student: "Alice",   class: "10A", score: 85 },
  { student: "Bob",     class: "10A", score: 72 },
  { student: "Charlie", class: "10A", score: 91 },
  { student: "Diana",   class: "10B", score: 68 },
  { student: "Eve",     class: "10B", score: 88 }
]);

How It Works

Class 10A top scorer is Charlie (91); class 10B top scorer is Eve (88)—clear targets for verifying $top output.

Example 2 — Top scorer per class

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      topScorer: {
        $top: {
          output: { name: "$student", score: "$score" },
          sortBy: { score: -1 }
        }
      }
    }
  },
  { $sort: { _id: 1 } }
]);

/* Result:
[
  { _id: "10A", topScorer: { name: "Charlie", score: 91 } },
  { _id: "10B", topScorer: { name: "Eve", score: 88 } }
]
*/

How It Works

Within each class group, MongoDB sorts by descending score and returns the top document’s projected fields.

📈 Practical Patterns

Return full documents, compare accumulators, and handle ties.

Example 3 — Return the full document with $$ROOT

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

// topRecord contains student, class, score, _id fields

How It Works

$$ROOT refers to the current document in the group during accumulation—useful when downstream stages need every field.

Example 4 — $top vs $max

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      maxScore: { $max: "$score" },
      topStudent: {
        $top: {
          output: { name: "$student", score: "$score" },
          sortBy: { score: -1 }
        }
      }
    }
  }
]);

/* 10A:
  maxScore: 91
  topStudent: { name: "Charlie", score: 91 }
  — same number, but $top also gives you the name */
*/

How It Works

Use both in the same $group when dashboards show the peak value and the record that achieved it.

Example 5 — Tie-break with secondary sort

When two students share the highest score, add a secondary key so ranking is predictable:

mongosh
db.scores.aggregate([
  {
    $group: {
      _id: "$class",
      topScorer: {
        $top: {
          output: { name: "$student", score: "$score" },
          sortBy: { score: -1, student: 1 }
        }
      }
    }
  }
]);

// If Charlie and Chris both score 91, student: 1
// puts Charlie before Chris — Charlie wins the tie

How It Works

Always add tie-breakers (name, timestamp, _id) when business rules require deterministic winners.

🧠 How $top Works

1

Documents bucketed

$group assigns each document to a group via _id.

Group
2

Sorted within group

sortBy ranks documents inside each bucket independently.

Sort
3

Top document selected

The first document in that sort order becomes the accumulator result.

Pick
=

output returned

The output expression shapes what fields appear in the final object.

📝 Notes

  • $top requires MongoDB 5.2+—verify server version before deploying.
  • sortBy is mandatory—there is no default sort order.
  • Result is one document per group, not an array (use $topN for many).
  • Ties may pick an arbitrary winner unless you add secondary sortBy keys.
  • On older MongoDB, approximate with $sort + $group + $first patterns (less efficient).
  • Previous topic: $sum. Next: $topN.

Conclusion

$top answers “which single record is at the high end of my ranking?” inside each group. Define sortBy carefully, project with output, and add tie-breakers when duplicates matter.

Pair with $max for the numeric peak alone, or move to $topN when you need several top-ranked documents per bucket.

💡 Best Practices

✅ Do

  • Always specify sortBy explicitly—match your business definition of “top”
  • Add secondary sort keys (student, _id) to break ties
  • Use $$ROOT when downstream stages need the full document
  • Put $match before $group to shrink working sets
  • Confirm MongoDB 5.2+ in staging before production rollout

❌ Don’t

  • Confuse $top with $topN (one doc vs array)
  • Expect $max to return student names—it only returns the maximum value
  • Rely on tie order without extra sortBy fields
  • Use on MongoDB versions before 5.2 without a fallback pipeline
  • Forget that sort direction changes which document is “top”

Key Takeaways

Knowledge Unlocked

Five things to remember about $top

Use these points when ranking documents inside $group.

5
Core concepts
📦 02

sortBy

Required ranking spec.

Syntax
👤 03

vs $max

Doc vs scalar value.

Compare
📄 04

$$ROOT

Return full record.

Pattern
🔢 05

5.2+

Check server version.

Version

❓ Frequently Asked Questions

$top returns one document per $group—the document ranked first according to the sortBy order you specify. It is useful when you need the whole record (name, score, date), not just a single field value.
Inside the $group stage: { winner: { $top: { output: "$$ROOT", sortBy: { score: -1 } } } }. It requires both output and sortBy.
$max returns the largest value of one field (e.g. the number 91). $top returns an entire document—the student or order that sits at the top of your sort order.
$top returns exactly one top-ranked document. $topN returns N top documents as an array. Use $top when you only need the single best record per group.
$top was added in MongoDB 5.2 as part of the $top/$bottom accumulator family. Upgrade the server or use $sort + $first/$last patterns on older versions.
sortBy defines ranking within each group—same rules as $sort. Use { score: -1 } for highest score first (top = best score), or { date: -1 } for the most recent document at the top.
Did you know?

$top and $bottom were added together in MongoDB 5.2 to replace fragile $sort + $group + $first recipes for ranked group results. Before 5.2, developers often sorted the entire collection globally and hoped group order stayed correct—$top ranks inside each bucket independently. See the official $top docs.

Continue the Accumulators Series

Pick the single top record with $top, then learn $topN for multiple ranked results.

Next: $topN →

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