Definición
Sintaxis
{ $maxN: { input: <expression>, n: <expression> } }
inputespecifica una expresión que es la entrada a$maxN. Se evalúa para cada elemento del grupo y$maxNpreserva los valoresnmáximos.nlimita la cantidad de resultados por grupo yndebe ser una expresión numérica positiva que sea constante o dependa del valor de_idpara$group.
Comportamiento
Valores nulos y faltantes
$maxNfiltra los valores nulos y ausentes.
Considera la siguiente agregación que devuelve los n documentos máximos de un grupo:
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", maximumThreeScores: { $maxN: { input: "$score", n: 4 } } } } ] )
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.El campo
maximumThreeScoresse especifica como$maxNconinput : "$score"y devuelto como un arreglo.Dado que solo hay 3 documentos con
scores,maxNdevuelve un máximo de 3 camposscoreaunquen = 4.
[ { _id: 'G1', maximumThreeScores: [ 3, 2, 1 ] } ]
Comparación de los acumuladores $maxN y $topN
Tanto los acumuladores $maxN como los $topN pueden lograr resultados similares.
En general:
$maxNtiene la ventaja de encontrar valores máximos sin ningún orden de clasificación específico. Si desea conocer los valores máximos de losndocumentos,$maxNutilice.Si garantizar un orden de clasificación específico es un requisito, utiliza
$topN.Utiliza
$topNsi no tienes la intención de ordenar los valores de salida.
Restricciones
Compatibilidad con funciones de ventana y expresiones de agregación
Puede usar $maxN como un acumulador.
$maxN está soportado como una expresión de agregación.
$maxN se admite window operator como.
Consideraciones sobre el límite de memoria
Las pipelines de agregación que llaman a $maxN están sujetas al límite de 100 MB. Si se supera este límite para un grupo individual, la agregación falla con un error.
Ejemplos
Considera una colección gamescores con los siguientes documentos:
db.gamescores.insertMany([ { playerId: "PlayerA", gameId: "G1", score: 31 }, { playerId: "PlayerB", gameId: "G1", score: 33 }, { playerId: "PlayerC", gameId: "G1", score: 99 }, { playerId: "PlayerD", gameId: "G1", score: 1 }, { playerId: "PlayerA", gameId: "G2", score: 10 }, { playerId: "PlayerB", gameId: "G2", score: 14 }, { playerId: "PlayerC", gameId: "G2", score: 66 }, { playerId: "PlayerD", gameId: "G2", score: 80 } ])
Encuentra Scores máxima en una sola partida
Puedes utilizar el acumulador $maxN para encontrar las tres puntuaciones máximas en un solo juego.
db.gamescores.aggregate( [ { $match : { gameId : "G1" } }, { $group: { _id: "$gameId", maxThreeScores: { $maxN: { input: ["$score","$playerId"], n:3 } } } } ] )
El ejemplo de canalización:
Utiliza para filtrar los resultados según un
$matchúnico.gameIdEn esteG1caso,.Usa para agrupar los
$groupresultadosgameIdpor. En esteG1caso,.Especifica los campos que son datos para
$maxNconinput : ["$score","$playerId"].Utiliza
$maxNpara devolver los tres elementos de puntuación máximos para el juegoG1conn : 3.
La operación devuelve los siguientes resultados:
[ { _id: 'G1', maxThreeScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] } ]
Encontrar las tres puntuaciones máximas en varios juegos
Puede usar el acumulador $maxN para encontrar los puntajes máximos de n en cada juego.
db.gamescores.aggregate( [ { $group: { _id: "$gameId", maxScores: { $maxN: { input: ["$score","$playerId"], n: 3 } } } } ] )
El ejemplo de canalización:
Utiliza
$grouppara agrupar los resultados porgameId.Utiliza
$maxNpara devolver los tres elementos de puntuación máximos para cada juego conn: 3.Especifica los campos que son datos para
$maxNconinput: ["$score","$playerId"].
La operación devuelve los siguientes resultados:
[ { _id: 'G1', maxScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] }, { _id: 'G2', maxScores: [ [ 80, 'PlayerD' ], [ 66, 'PlayerC' ], [ 14, 'PlayerB' ] ] } ]
Cálculo n de según la clave de grupo para $group
También puede asignar el valor n dinámicamente. En este ejemplo,$cond se utiliza la expresión en el gameId campo.
db.gamescores.aggregate([ { $group: { _id: {"gameId": "$gameId"}, gamescores: { $maxN: { input: ["$score","$playerId"], n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } } } } } } ] )
El ejemplo de canalización:
Utiliza
$grouppara agrupar los resultados porgameId.Especifica los campos que se ingresan para
$maxNconinput : ["$score","$playerId"].Si el
gameIdesG2entoncesnes 1, de lo contrariones 3.
La operación devuelve los siguientes resultados:
[ { _id: { gameId: 'G2' }, gamescores: [ [ 80, 'PlayerD' ] ] }, { _id: { gameId: 'G1' }, gamescores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] } ]