MongoDB $firstN Accumulator

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

What Is $firstN?

$firstN is a MongoDB accumulator for the $group stage (MongoDB 5.2+). For each group it returns an array of the first N input values—in the order documents arrive at $group.

Remember
$firstN = first N values per group (as an array)

input → expression to collect (e.g. "$product")
n     → how many to keep (positive integer)

Order comes from documents entering $group
→ $sort first when “first” must mean highest / earliest
vs $first → one value; $firstN → up to N values
UsePrefer
First N values after you sorted$firstN
Only the first single value$first
Rank top N inside $group$topN

How to Use $firstN in MongoDB

Two keys drive every call: input and n.

  1. Optionally $sort so documents enter $group in the order you want.
  2. Put $firstN inside $group on an output field.
  3. Set input to the field or expression to collect.
  4. Set n to how many leading values to keep.
KeyRequired?Role
inputYesExpression to take from each document
nYesPositive integer (or expression based on group key)
$group._idYesGroup key ("$store", null, …)

Pseudocode

Pseudocode
// optional but recommended when order matters:
documents = sort(documents, sortSpec)

for each group:
    result = []
    for each document in group (arrival order):
        if result.length < n:
            result.append(evaluate(input))
    emit { _id: groupKey, field: result }

Cheat Sheet

Keep these facts handy while collecting the first N values.

TopicDetail
Stage$group accumulator (also array / expression form)
Syntax{ $firstN: { input: "$field", n: 3 } }
ReturnsArray of up to n values
OrderDocument arrival order—use $sort first
Short groupsFewer than n docs → return all of them
VersionMongoDB 5.2+

Live Preview

Watch the first 2 products per store after sorting by amount descending. Sample: A/Laptop 1200, A/Mouse 25, A/Keyboard 75, A/Monitor 300, B/Laptop 1100, B/Headset 80.

Simulates $sort by amount descending, then $firstN with n: 2 on product.

Result
store A after sort (amount ↓): Laptop, Monitor, Keyboard, Mouse
  → first 2 = ["Laptop", "Monitor"]
store B after sort (amount ↓): Laptop, Headset
  → first 2 = ["Laptop", "Headset"]

[
  { _id: "A", firstProducts: ["Laptop", "Monitor"] },
  { _id: "B", firstProducts: ["Laptop", "Headset"] }
]

Worked Walkthrough — First 2 by Amount

Six orders, two stores. Sort by amount high to low, then keep the first two product names per store.

Calculation
Documents (before sort):
  A: Laptop 1200, Mouse 25, Keyboard 75, Monitor 300
  B: Laptop 1100, Headset 80

$sort: { amount: -1 }

store "A" arrival order:
  Laptop, Monitor, Keyboard, Mouse
  $firstN n:2 → ["Laptop", "Monitor"]

store "B" arrival order:
  Laptop, Headset
  $firstN n:2 → ["Laptop", "Headset"]

Output:
  { _id: "A", firstProducts: ["Laptop", "Monitor"] }
  { _id: "B", firstProducts: ["Laptop", "Headset"] }

MongoDB Examples

We use a tiny orders list. First we take the first two products in document order. Then we $sort by amount and take the first two again. Run these in mongosh after inserting the sample data once.

Example 1 — Sample Data

Imagine six orders across stores A and B. Each document has a store, product, and amount.

mongosh
db.orders.insertMany([
  { store: "A", product: "Laptop", amount: 1200 },
  { store: "A", product: "Mouse", amount: 25 },
  { store: "A", product: "Keyboard", amount: 75 },
  { store: "A", product: "Monitor", amount: 300 },
  { store: "B", product: "Laptop", amount: 1100 },
  { store: "B", product: "Headset", amount: 80 }
]);

How the Data Is Stored in MongoDB

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

mongosh
db.orders.find()

Read each document like this:

Field in MongoDBMeaningExample
storeWhich store"A"
productWhat was sold"Laptop"
amountOrder amount1200
Picture
Store A order stream (as inserted):
  Laptop, Mouse, Keyboard, Monitor

Next: $firstN keeps the first N values in that order.

How It Works

  1. Insert once. The sample command adds 6 documents to orders.
  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 $firstN in the next examples.

Example 2 — First 2 in Document Order

Goal: for each store, keep the first two product values as they appear in the collection (no sort). Store A has four orders, so we only keep the first two.

mongosh
db.orders.aggregate([
  {
    $group: {
      _id: "$store",
      firstProducts: {
        $firstN: {
          input: "$product",
          n: 2
        }
      }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Split by store. _id: "$store" makes groups "A" and "B".
  2. Read product names. input: "$product" is what gets pushed into the result array.
  3. Stop at n. With n: 2, store A keeps Laptop and Mouse, then ignores Keyboard and Monitor.
  4. Short groups are fine. Store B only has two orders, so both products appear.
  5. Need one value only? Use $first instead of $firstN.

Example 3 — First 2 After $sort

Goal: first two products per store by highest amount. $firstN does not sort—so we $sort before $group.

mongosh
db.orders.aggregate([
  // Highest amount first — this sets arrival order for $firstN
  { $sort: { amount: -1 } },
  {
    $group: {
      _id: "$store",
      firstProducts: {
        $firstN: {
          input: "$product",
          n: 2
        }
      }
    }
  },
  { $sort: { _id: 1 } }
]);

How It Works

  1. Sort the pipeline. { amount: -1 } puts expensive orders ahead of cheap ones.
  2. Group still buckets by store. Within each bucket, documents keep the sorted order.
  3. First N now means “top by amount”. Store A: Laptop (1200), then Monitor (300).
  4. Contrast Example 2. Without sort, store A was Laptop + Mouse. With sort, Mouse is replaced by Monitor.
  5. Rank inside the accumulator? Use $topN with sortBy instead of a separate $sort.

Edge Cases & Pitfalls

Check these before shipping a first-N report.

order

$firstN does not sort

Without $sort, “first” only means document arrival order. Add $sort whenever business order matters.

n

Fewer than n documents is OK

The array is simply shorter. You never get padding or an error for a short group.

null

Null and missing become null

$firstN does not skip nulls. Filter with $match if you do not want them in the array.

version

Requires MongoDB 5.2+

Older servers lack $firstN. On older versions, combine $sort, $group, and $push with a later slice.

Performance Notes

ApproachCostBest for
$firstNKeeps at most n values per groupAlready-sorted pipelines
$sort + $firstNSort cost + small accumulatorTop-N style lists with upstream sort
$topNRanks inside $groupWhen you prefer sortBy in the accumulator

Prefer $firstN when documents are already ordered. Keep n small and filter early with $match so fewer documents enter each group.

Key Takeaways

  • Role: array of the first N input values per group.
  • Keys: input + n (both required).
  • Order: arrival order—add $sort when it matters.
  • vs $topN: sorted upstream vs sortBy inside the accumulator.

One line: $firstN keeps the leading N values per group—sort first when “first” means something specific.

Frequently Asked Questions

$firstN returns an array of the first N input values from each $group bucket, based on the order documents arrive at $group. Use it for the first three orders per store or the leading N events after you $sort.
Inside $group: { firstThree: { $firstN: { input: "$product", n: 3 } } }. Both input and n are required. It can also slice the first N elements from an array in $project / $addFields.
Yes whenever order matters. $firstN does not sort—it takes the first N documents as they enter each group. Add $sort before $group so “first” means earliest, cheapest, or highest.
$first returns one value from the first document. $firstN returns an array of up to N values. Use $first for a single field; use $firstN for a short list.
$firstN assumes documents are already ordered (usually via $sort). $topN sorts inside $group with sortBy. Prefer $firstN when you sorted upstream; prefer $topN when ranking happens in the accumulator.
$firstN returns every available element—never more than exist. A group with two documents and n: 3 yields an array of two items.

Next: $last

Return a single value from the last document in each group.

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