Definition
Returns an aggregation of the first n elements in a group. The results are meaningful only if the input data to the grouping stage has a defined sort order. If the group contains fewer than n elements, $firstN returns all elements in the group.
The $firstN accumulator is available in these stages:
Note
Disambiguation
This page describes $firstN when used as an accumulator. Accumulators return a single aggregated value like sum, maximum, or minimum across a group of input documents.
You can also use $firstN in these other contexts:
$firstN (expression), which returns the specified number of elements from the beginning of an array.$firstN (window function), which is used in the$setWindowFieldsstage to return the firstnvalues from documents in a particular window.
Syntax
{ $firstN: { input: <expression>, n: <expression> } }
Options
Field | Type | Description |
|---|---|---|
| Expression | The |
| Expression | The number of elements that |
Behavior
Null and Missing Values
$firstNdoes not filter out null values.$firstNconverts missing values to null.
Comparison of $firstN and $topN
Both $firstN and $topN accumulators can accomplish similar results.
In general:
If the documents coming into
$groupare already ordered, you should use$firstN.If you're sorting and selecting the top
nelements then you can use$topNto accomplish both tasks with one accumulator.
Examples
The examples on this page use the movies collection in the sample_mflix sample dataset. To learn how to load the sample dataset into your MongoDB deployment, see Import Sample Data Into Your Atlas Deployment.
Find the First Three Movies for a Single Genre
You can use the $firstN accumulator to find the first three movies in a single genre.
db.movies.aggregate( [ { $match: { genres: "Horror" } }, { $sort: { year: 1 } }, { $group: { _id: "Horror", firstThreeMovies: { $firstN: { input: [ "$title", "$year" ], n: 3 } } } } ] )
The preceding pipeline:
Uses
$matchto filter the results to movies whereHorroris included in thegenresarray.Sorts the results by
yearin ascending order.Groups all resulting documents into a single group.
Specifies the fields that are input for
$firstNwithinput : ["$title", "$year"].Uses
$firstNto return the first three documents for theHorrorgenre withn: 3.
Find the First Three Movies Across Multiple Genres
You can use the $firstN accumulator to find the first n input fields in each genre.
db.movies.aggregate( [ { $unwind: "$genres" }, { $sort: { year: 1 } }, { $group: { _id: "$genres", movies: { $firstN: { input: [ "$title", "$year" ], n: 3 } } } }, { $sort: { _id: 1 } }, { $limit: 5 } ] )
The preceding pipeline:
Uses
$unwindto create a separate document for each genre in thegenresarray.Sorts the results by
yearin ascending order.Uses
$groupto group the results bygenres.Uses
$firstNto return the first three documents for each genre withn: 3.Specifies the fields that are input for
$firstNwithinput : ["$title", "$year"].Limits the output to five documents to improve readability.
Set n Based on the Group Key
You can assign the value of n dynamically based on the group key. In this example, the $cond expression uses the rated field to change the value of n:
db.movies.aggregate([ { $match: { rated: { $in: ["G", "PG", "PG-13", "R"] } } }, { $sort: { title: 1 } }, { $group: { _id: {"rated": "$rated"}, movies: { $firstN: { input: "$title", n: { $cond: { if: { $eq: ["$rated", "PG"] }, then: 3, else: 1 } } } } } } ] )
The preceding pipeline:
Filters for movies with ratings of
G,PG,PG-13, orR.Sorts the results alphabetically by
title.Groups movies by
rated(the movie rating).Uses the
$condexpression to return3movies forPG-rated movies and1movie for all other ratings.
In the output, the PG rating returns 3 movies, while G, PG-13, and R ratings each return 1 movie.