Definición
Devuelve una agregación de los n elementos principales dentro de un grupo, de acuerdo con el orden de clasificación especificado. Si el grupo contiene menos de n elementos, $topN devuelve todos los elementos del grupo.
Nota
Otros usos de $topN
Esta página describe $topN cuando se utiliza como acumulador. Los acumuladores devuelven un valor agregado a partir de un grupo de documentos de entrada.
También puedes usar $topN en estos otros contextos:
$topN (window function), que devuelve los elementosnsuperiores de los documentos en una ventana particular según el orden de clasificación especificado.$topN (expression), que devuelve losnelementos superiores de una matriz.
Sintaxis
{ $topN: { n: <expression>, sortBy: { <field1>: <sort order>, <field2>: <sort order> ... }, output: <expression> } }
Campo | Tipo | Descripción |
|---|---|---|
| expresión | Determina el número máximo de resultados devueltos por grupo. |
| Documento | Especifica el orden de los resultados, con una sintaxis similar a |
| expresión | Especifica la salida para cada elemento del grupo. Puede ser cualquier expresión. |
Comportamiento
Valores nulos y faltantes
$topNno filtra los valores nulos.$topNconvierte los valores faltantes a nulos, que se conservan en el resultado.
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: { $topN: { output: [ "$playerId", "$score" ], sortBy: { "score": 1 }, n: 3 } } } } ] )
En este ejemplo:
$documentscrea los documentos literales que contienen las puntuaciones de los jugadores.$groupagrupa los documentos porgameId. Este ejemplo tiene solo ungameId,G1.PlayerDtiene una puntuación faltante yPlayerEtiene unscorenulo. Estos valores se consideran ambos nulos.Los campos
playerIdyscorese especifican comooutput : ["$playerId"," $score"]y se devuelven como valores de un arreglo.Debido al
sortBy: { "score" : 1 }, los valores nulos se ordenan al principio del arreglo deplayerIddevueltos.
[ { _id: 'G1', playerId: [ [ 'PlayerD', null ], [ 'PlayerE', null ], [ 'PlayerA', 1 ] ] } ]
Orden de clasificación del tipo de datos BSON
Al ordenar diferentes tipos, se utiliza el orden de los tipos de datos BSON para determinar el orden. Como ejemplo, consideremos una colección cuyos valores consisten en cadenas y números.
En una ordenación ascendente, los valores de string se ordenan después de los valores numéricos.
En una ordenación descendente, los valores de string se ordenan antes que los valores numéricos.
db.aggregate( [ { $documents: [ { playerId: "PlayerA", gameId: "G1", score: 1 }, { playerId: "PlayerB", gameId: "G1", score: "2" }, { playerId: "PlayerC", gameId: "G1", score: "" } ] }, { $group: { _id: "$gameId", playerId: { $topN: { output: ["$playerId","$score"], sortBy: {"score": -1}, n: 3 } } } } ] )
En este ejemplo:
PlayerAtiene una puntuación entera.PlayerBtiene una puntuación de string"2".PlayerCtiene un puntaje de string vacía.
Debido a que el ordenamiento es descendente { "score" : -1 }, los valores de literales de string se ordenan antes de la puntuación numérica de PlayerA:
[ { _id: "G1", playerId: [ [ "PlayerB", "2" ], [ "PlayerC", "" ], [ "PlayerA", 1 ] ] } ]
Ejemplos
Los ejemplos de esta página utilizan datos del conjunto de datos sample_mflix. Para obtener más información sobre cómo cargar este conjunto de datos en su implementación autogestionada de MongoDB, consulte Cargar el conjunto de datos de ejemplo. Si realizó alguna modificación en las bases de datos de ejemplo, es posible que deba eliminarlas y volver a crearlas para ejecutar los ejemplos de esta página.
Encuentra las tres películas mejor valoradas de un mismo género.
Puedes usar el acumulador $topN para encontrar las tres películas mejor valoradas del género Short.
db.movies.aggregate( [ { $match: { genres: "Short", "imdb.rating": { $gt: 0 } } }, { $group: { _id: "Short", topRatedMovies: { $topN: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1, title: 1 }, n: 3 } } } } ] )
La pipeline de ejemplo:
Utiliza
$matchpara restringir la entrada a las películasShortque incluyen un valorimdb.rating.Utiliza
$grouppara colocar las películas coincidentes en un único grupoShort.Utiliza
sortBy: { "imdb.rating": -1, title: 1 }para clasificar las películas por calificación ytitlecomo criterio de desempate.Especifica los campos devueltos por
$topNconoutput: [ "$title", "$imdb.rating" ].Utiliza
$topNpara devolver las tres películas que mejor coinciden conn: 3.
Encuentra las películas mejor valoradas de cada género.
Puedes usar el acumulador $topN para encontrar las películas mejor valoradas de cada género.
db.movies.aggregate( [ { $unwind: "$genres" }, { $match: { "imdb.rating": { $gt: 0 } } }, { $group: { _id: "$genres", topRatedMovies: { $topN: { output: [ "$title", "$imdb.rating" ], sortBy: { "imdb.rating": -1, title: 1 }, n: 3 } } } }, { $sort: { _id: 1 } }, { $limit: 5 } ] )
La pipeline de ejemplo:
Utiliza
$unwindpara expandir el arraygenresde cada película.Utiliza
$matchpara conservar solo los documentos que incluyen un valorimdb.rating.Utiliza
$grouppara agrupar los resultados por género.Especifica los campos devueltos por
$topNconoutput: [ "$title", "$imdb.rating" ].Utiliza
sortBy: { "imdb.rating": -1, title: 1 }para clasificar las películas por calificación y utilizatitlecomo un criterio de desempate determinista.Utiliza
$topNpara devolver las tres mejores películas de cada género conn: 3.
Establecer n dinámicamente en función de la clave de grupo.
Puedes asignar el valor de n dinámicamente. El siguiente ejemplo utiliza la expresión $cond para devolver diferentes cantidades de películas según su clasificación por edades.
db.movies.aggregate( [ { $match: { rated: { $in: [ "G", "PG", "PG-13", "R" ] }, "imdb.rating": { $gt: 0 } } }, { $group: { _id: { rated: "$rated" }, movies: { $topN: { output: { title: "$title", rating: "$imdb.rating" }, n: { $cond: { if: { $eq: [ "$rated", "PG" ] }, then: 3, else: 1 } }, sortBy: { "imdb.rating": -1 } } } } }, { $sort: { "_id.rated": 1 } } ] )
La pipeline de ejemplo:
Utiliza
$matchpara conservar solo las películas con clasificaciones de contenidoG,PG,PG-13oRque incluyan un valorimdb.rating.Utiliza
$grouppara agrupar los resultados por calificación de contenido con_id: { rated: "$rated" }.Especifica los campos devueltos por
$topNconoutput: { title: "$title", rating: "$imdb.rating" }.Si la clasificación de contenido es
PG, entoncesnes 3. De lo contrario,nes 1.Utiliza
sortBy: { "imdb.rating": -1 }para encontrar las mejoresnpelículas según la puntuación de IMDb.Ordena los resultados por calificación de contenido en orden alfabético.