Docs Menu
Docs Home
/ /
Etapas de la pipeline de agregación

$sort (agregación)

$sort

Ordena todos los documentos de entrada y los devuelve al pipeline en orden.

Puedes usar $sort para implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube

  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

La etapa $sort tiene la siguiente forma de prototipo:

{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }

$sort toma un documento que especifica los campos por orden y el orden de clasificación respectivo. <sort order> puede tener uno de los siguientes valores:

Valor
Descripción

1

Ordenar de forma ascendente.

-1

Ordenar de forma descendente.

{ $meta: "textScore" }

Ordenar por los metadatos textScore calculados en orden descendente
orden. Consulte Orden de metadatos de puntuación de texto para ver un ejemplo.

Si se ordena en varios campos, el orden de clasificación se evalúa de izquierda a derecha. Por ejemplo, en el formulario anterior, los documentos se ordenan primero por <field1>. Luego, los documentos con los mismos valores <field1> se ordenan adicionalmente por <field2>.

$sort es una etapa de bloqueo, que hace que el pipeline espere a que se recuperen todos los datos de entrada para la etapa de bloqueo antes del procesamiento de los datos. Una etapa de bloqueo puede reducir el rendimiento porque disminuye el procesamiento paralelo en un pipeline con múltiples etapas. Una etapa de bloqueo también puede utilizar cantidades sustanciales de memoria para grandes conjuntos de datos.

  • Puedes ordenar sobre un máximo de 32 claves.

  • Proveer un patrón de ordenación con campos duplicados causa un error.

MongoDB no almacena documentos en una colección en un orden específico. Al ordenar en un campo que contiene valores duplicados, los documentos que contienen esos valores pueden ser devueltos en cualquier orden.

Si se desea un orden de clasificación coherente, se debe incluir al menos un campo en la clasificación que contenga valores únicos. La forma más sencilla de garantizar esto es incluir el campo _id en la query de ordenación.

Considere la siguiente colección restaurant:

db.restaurants.insertMany( [
{ "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan"},
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens"},
{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn"},
{ "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan"},
{ "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn"},
] )

El siguiente comando utiliza la etapa $sort para ordenar en el campo borough:

db.restaurants.aggregate(
[
{ $sort : { borough : 1 } }
]
)

En este ejemplo, el orden de clasificación puede ser inconsistente, ya que el campo borough contiene valores duplicados tanto para Manhattan como para Brooklyn. Los documentos se devuelven en orden alfabético por borough, pero el orden de aquellos documentos con valores duplicados para borough podría no ser el mismo en múltiples ejecuciones del mismo ordenamiento. Por ejemplo, aquí están los resultados de dos ejecuciones diferentes del comando mencionado anteriormente:

{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" }
{ "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" }
{ "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" }
{ "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" }
{ "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn" }
{ "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn" }
{ "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan" }
{ "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan" }
{ "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens" }

Aunque los valores para borough aún se ordenan alfabéticamente, el orden de los documentos que contienen valores duplicados para borough (es decir, Manhattan y Brooklyn) no son lo mismo.

Para lograr una clasificación coherente, agrega un campo que contenga valores exclusivamente únicos a la clasificación. El siguiente comando usa la etapa $sort para ordenar tanto en el campo borough como en el campo _id:

db.restaurants.aggregate(
[
{ $sort : { borough : 1, _id: 1 } }
]
)

Dado que siempre se garantiza que el campo _id contendrá valores exclusivamente únicos, el orden de clasificación devuelto siempre será el mismo en múltiples ejecuciones del mismo ordenamiento.

Cuando MongoDB ordena documentos por un campo cuyo valor es un arreglo, la clave de ordenación depende de si el orden es ascendente o descendente:

  • En una ordenación ascendente, la clave de ordenación es el valor más bajo del arreglo.

  • En una ordenación descendente, la clave de ordenación es el valor más alto del arreglo.

El filtro de query no afecta la selección de la clave de ordenación.

Por ejemplo, cree una colección shoes con estos documentos:

db.shoes.insertMany( [
{ _id: 'A', sizes: [ 7, 11 ] },
{ _id: 'B', sizes: [ 8, 9, 10 ] }
] )

Las siguientes queries ordenan los documentos por el campo sizes en orden ascendente y descendente:

// Ascending sort
db.shoes.aggregate( [
{
$sort: { sizes: 1 }
}
] )
// Descending sort
db.shoes.aggregate( [
{
$sort: { sizes: -1 }
}
] )

Ambas queries anteriores devuelven el documento con _id: 'A' primero porque los tamaños 7 y 11 son el más bajo y el más alto en las entradas del arreglo sizes, respectivamente.

Para los campos a ordenar, establezca el orden de clasificación en 1 o -1 para especificar un orden ascendente o descendente, respectivamente, como en el siguiente ejemplo:

db.users.aggregate(
[
{ $sort : { age : -1, posts: 1 } }
]
)

Esta operación ordena los documentos de la colección users, en orden descendente según el campo age y luego en orden ascendente según el valor en el campo posts.

Al comparar valores de diferentes BSON types en operaciones de ordenación, MongoDB utiliza el siguiente orden de comparación, de menor a mayor:

  1. MinKey (tipo interno)

  2. Nulo

  3. Números (enteros, largos, dobles, decimales)

  4. Símbolo, string

  5. Objeto

  6. Arreglo

  7. BinData

  8. ObjectId

  9. Booleano

  10. fecha

  11. Marca de tiempo

  12. Expresión regular

  13. Código JavaScript

  14. MaxKey (tipo interno)

Para obtener detalles sobre el orden de comparación o clasificación para tipos específicos, consulte el orden de comparación o clasificación.

Nota

$text Proporciona funciones de consulta de texto para implementaciones autogestionadas (no Atlas). Para los datos alojados en MongoDB Atlas, MongoDB ofrece una solución mejorada de consulta de texto completo: Atlas Search.

Para un pipeline que incluye $text, puede ordenar por puntuación de relevancia descendente mediante la expresión { $meta: "textScore" }. En el documento { <sort-key> }, establezca la expresión { $meta: "textScore" } en un nombre de campo arbitrario. El sistema de query ignora el nombre del campo. Por ejemplo:

db.users.aggregate(
[
{ $match: { $text: { $search: "operating" } } },
{ $sort: { score: { $meta: "textScore" }, posts: -1 } }
]
)

Esta operación utiliza el operador $text para hacer coincidir los documentos, y luego ordena primero por los metadatos "textScore" en orden descendente, y luego por el campo posts en orden descendente. El sistema de query ignora el nombre del campo score en el documento de ordenación. En este pipeline, los metadatos "textScore" no se incluyen en la proyección y no se devuelven como parte de los documentos coincidentes. Consulte $meta para obtener más información.

Cuando un $sort precede a un $limit y no hay etapas intermedias que modifiquen el número de documentos, el optimizador puede fusionar el $limit con el $sort. Esto permite que la operación de $sort solo mantenga los n mejores resultados a medida que avanza, donde n es el límite especificado, y garantiza que MongoDB solo necesite almacenar n elementos en memoria. Esta optimización sigue aplicándose cuando allowDiskUse es true y los elementos de n superan el límite de memoria de agregación.

Las optimizaciones están sujetas a cambios entre versiones.

La etapa tiene un límite $sort de 100 megabytes de RAM para ordenaciones en memoria. De forma predeterminada, si la etapa supera este límite, $sort genera un error. Para permitir que el procesamiento de la canalización ocupe más espacio, utilice la opción allowDiskUse para habilitar las etapas de la canalización de agregación para escribir datos en archivos temporales.

Tip

El operador $sort puede aprovechar un índice si se utiliza en la primera etapa de una pipeline o si sólo está precedido por una etapa $match.

Cuando utiliza el $sort en un clúster particionado, cada partición ordena sus documentos de resultado a través de un índice cuando esté disponible. Luego, el mongos o uno de los fragmentos realiza un ordenamiento por fusión en flujo.

Volver

$skip

En esta página