Definition
Returns the top element within a group according to the specified sort order.
Note
Disambiguation
This page describes $top when used as an accumulator. Accumulators return a single aggregated value across a group of input documents.
You can also use $top in these other contexts:
$top (expression operator), which returns the top element of an array based on a specified sort order.$top (window function), used in the$setWindowFieldsstage to return the top element from documents in a particular window.
Syntax
{ $top: { sortBy: { <field1>: <sort order>, <field2>: <sort order> ... }, output: <expression> } }
Field | Necessity | Description |
|---|---|---|
sortBy | Required | Specifies the order of results, with syntax similar to |
output | Required | Represents the output for each element in the group and can be any expression. |
Behavior
Null and Missing Values
Consider the following aggregation that returns the top document from a group of scores:
$topdoes not filter out null values.$topconverts missing values to null.
db.aggregate( [ { $documents: [ { playerId: "PlayerA", gameId: "G1", score: 1 }, { playerId: "PlayerB", gameId: "G1", score: 2 }, { playerId: "PlayerC", gameId: "G1", score: 3 }, { playerId: "PlayerD", gameId: "G1"}, { playerId: "PlayerE", gameId: "G1", score: null } ] }, { $group: { _id: "$gameId", playerId: { $top: { output: [ "$playerId", "$score" ], sortBy: { "score": 1 } } } } } ] )
In this example:
$documentscreates the literal documents that contain player scores.$groupgroups the documents bygameId. This example has only onegameId,G1.PlayerDhas a missing score andPlayerEhas a nullscore. These values are both considered as null.The
playerIdandscorefields are specified asoutput : ["$playerId"," $score"]and returned as array values.Specify the sort order with
sortBy: { "score": 1 }.PlayerDandPlayerEtied for the top element.PlayerDis returned as the topscore.To have more deterministic tie breaking behavior for multiple null values, add more fields to
sortBy.
BSON Data Type Sort Ordering
When sorting different types, the order of BSON data types is used to determine ordering. As an example, consider a collection whose values consist of strings and numbers.
In an ascending sort, string values are sorted after numeric values.
In a descending sort, string values are sorted before numeric values.
In this example:
PlayerAhas an integer score.PlayerBhas a string"2"score.PlayerChas an empty string score.
Because the sort is in descending { "score": -1 }, string values are sorted before PlayerA's numeric score. $top returns the first element after sorting, which is PlayerB:
db.aggregate( [ { $documents: [ { playerId: "PlayerA", gameId: "G1", score: 1 }, { playerId: "PlayerB", gameId: "G1", score: "2" }, { playerId: "PlayerC", gameId: "G1", score: "" } ] }, { $group: { _id: "$gameId", playerId: { $top: { output: [ "$playerId", "$score" ], sortBy: { "score": -1 } } } } } ] )
Examples
The examples on this page use data from the sample_mflix dataset. For details on how to load this dataset into your self-managed MongoDB deployment, see Load the Sample Dataset. If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.
Find the Top Rating in a Genre
You can use the $top accumulator to find the highest-rated movie in a genre.
db.movies.aggregate( [ { $match: { genres: "Comedy", "imdb.rating": { $gt: 0 } } }, { $group: { _id: "Comedy", highestRatedMovie: { $top: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1 } } } } } ] )
The example pipeline:
Uses
$matchto filter for Comedy movies with a positive IMDb rating.Uses
$groupto group all Comedy movies under a single"Comedy"group key.Specifies the fields that are output for
$topwithoutput : ["$title", "$imdb.rating"].Uses
sortBy: { "imdb.rating": -1 }to rank movies within the group by IMDb rating in descending order, which determines the movie that$topreturns.
Find the Top Rating Across Multiple Ratings
You can use the $top accumulator to find the highest-rated movie for each movie rating category.
db.movies.aggregate( [ { $match: { rated: { $in: [ "G", "PG", "PG-13", "R" ] }, "imdb.rating": { $gt: 0 } } }, { $group: { _id: "$rated", highestRatedMovie: { $top: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1 } } } } }, { $sort: { _id: 1 } } ] )
The example pipeline:
Uses
$matchto filter for movies in theG,PG,PG-13, andRcategories with a positive IMDb rating.Uses
$groupto group the results byrated.Uses
$topto return the highest-rated movie for each category.Specifies the fields that are output for
$topwithoutput : ["$title", "$imdb.rating"].Uses
sortBy: { "imdb.rating": -1 }to rank movies within each group by IMDb rating in descending order, which determines the movie that$topreturns.Uses
$sortto sort the results alphabetically by rating category.