En MongoDB, el cursor.sort()
El método especifica el orden en que la consulta devuelve documentos coincidentes.
El sort()
El método acepta un documento que especifica el campo para ordenar y el orden de clasificación. El orden de clasificación puede ser 1
para ascender o -1
por descender.
También puede especificar { $meta: "textScore" }
al hacer $text
búsquedas, para ordenar por el textScore
calculado metadatos en orden descendente.
Datos de muestra
Supongamos que tenemos una colección llamada pets
con los siguientes documentos:
{ "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 }
Ordenar en orden ascendente
Para ordenar en orden ascendente, usamos 1
para el orden de clasificación.
A continuación se muestra un ejemplo de una consulta que utiliza el $sort
operador para ordenar esa colección por el weight
campo en orden ascendente.
db.pets.find().sort({ weight: 1 })
Resultado:
{ "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 }
Ordenar en orden descendente
Para ordenar en orden descendente, usamos -1
para el orden de clasificación.
db.pets.find().sort({ weight: -1 })
Resultado:
{ "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 }
Ordenar por campos múltiples
Para ordenar por más de un campo, separe cada combinación de campo/orden de clasificación con una coma.
Ejemplo
db.pets.find().sort({ type: 1, weight: -1, _id: 1 })
Resultado:
{ "_id" : 8, "name" : "Snap", "type" : "Cat", "weight" : 12 } { "_id" : 4, "name" : "Scratch", "type" : "Cat", "weight" : 8 } { "_id" : 3, "name" : "Meow", "type" : "Cat", "weight" : 7 } { "_id" : 9, "name" : "Ruff", "type" : "Dog", "weight" : 30 } { "_id" : 1, "name" : "Wag", "type" : "Dog", "weight" : 20 } { "_id" : 2, "name" : "Bark", "type" : "Dog", "weight" : 10 } { "_id" : 7, "name" : "Punch", "type" : "Kangaroo", "weight" : 200 } { "_id" : 6, "name" : "Hop", "type" : "Kangaroo", "weight" : 130 } { "_id" : 5, "name" : "Bruce", "type" : "Kangaroo", "weight" : 100 }
En este ejemplo, ordenamos por type
campo en orden ascendente primero, luego por el weight
campo en orden descendente, luego por el _id
campo en orden ascendente.
Esto significa que, si hay varias mascotas del mismo tipo, esas mascotas se ordenan por su weight
en orden descendente. Si hay varias mascotas con el mismo tipo y peso, esas mascotas se ordenan por el _id
campo en orden ascendente. Si no hubiéramos incluido el _id
en el proceso de clasificación, las mascotas del mismo tipo y peso podrían aparecer en cualquier orden. Esto es cierto cada vez que ejecutamos la consulta. Sin tener un campo de clasificación en un campo único (como el _id
campo), sería completamente posible (incluso probable) que los resultados regresaran en un orden diferente cada vez que se ejecuta la consulta.
Clasificación de diferentes tipos
Al comparar valores de diferentes tipos de BSON, MongoDB utiliza el siguiente orden de comparación, de menor a mayor:
- MinKey (tipo interno)
- Nulo
- Números (ints, largos, dobles, decimales)
- Símbolo, Cadena
- Objeto
- matriz
- BinData
- Id. de objeto
- Booleano
- Fecha
- Marca de tiempo
- Expresión regular
- MaxKey (tipo interno)
Supongamos que tenemos una colección llamada publicaciones con los siguientes documentos:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
Observe que la primera date
El campo contiene una cadena de fecha, mientras que los otros dos documentos usan un objeto Fecha.
Observe también que la cadena de fecha contiene exactamente la misma fecha que el documento 3, y esta fecha es posterior a la fecha del documento 2.
Ordenemos por date
campos de esos documentos:
db.posts.find().sort({ date: 1 }).pretty()
Resultado:
{ "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") }
En este caso, ordenamos en orden ascendente, lo que significa que las fechas anteriores deben aparecer primero. Sin embargo, nuestro primer documento contiene una cadena de fecha en lugar de un objeto Fecha, por lo que llegó primero, aunque su fecha es posterior a la fecha del documento 2.
Aquí está de nuevo, pero en orden descendente:
db.posts.find().sort({ date: -1 }).pretty()
Resultado:
{ "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Una vez más, los diferentes tipos de datos se ordenan por separado dentro de sí mismos.
Ordenación de metadatos de puntuación de texto
Puede usar el { $meta: "textScore" }
argumento para ordenar por puntaje de relevancia descendente al usar $text
búsquedas.
Ejemplo
db.posts.find(
{ $text: { $search: "funny" } },
{ score: { $meta: "textScore" }}
).sort({ score: { $meta: "textScore" } }
).pretty()
Resultado:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z"), "score" : 0.6666666666666666 } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z"), "score" : 0.6 } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z", "score" : 0.5833333333333334 }
En este ejemplo, ordenamos por { $meta: "textScore" }
.
Desde MongoDB 4.4 la línea que va { score: { $meta: "textScore" }}
es opcional. Omitir esto omitirá la score
campo de los resultados. Por lo tanto, podemos hacer lo siguiente (desde MongoDB 4.4):
db.posts.find(
{ $text: { $search: "funny" } }
).sort({ score: { $meta: "textScore" } }
).pretty()
Resultado:
{ "_id" : 2, "title" : "Animals", "body" : "Animals are funny things...", "date" : ISODate("2020-01-01T00:00:00Z") } { "_id" : 3, "title" : "Oceans", "body" : "Oceans are wide and vast, but definitely not funny...", "date" : ISODate("2021-01-01T00:00:00Z") } { "_id" : 1, "title" : "Web", "body" : "Create a funny website with these three easy steps...", "date" : "2021-01-01T00:00:00.000Z" }
Haciendo $text
búsquedas como esta requieren que hayamos creado un índice de texto. Si no, un IndexNotFound
se devolverá el error.
Más información
Consulte la documentación de MongoDB para obtener más información.