cursor.sort()
Definição
cursor.sort(sort)
Importante
Método mongosh
Esta página documenta um método
mongosh
. Esta não é a documentação de um driver de idioma específico, como Node.js.Para drivers de API do MongoDB, consulte a documentação do driver do MongoDB específica da linguagem.
Especifica a ordem na qual a query retorna documentos correspondentes. Você deve aplicar
sort()
ao cursor antes de recuperar quaisquer documentos do banco de dados.
Compatibilidade
Você pode utilizar o cursor.sort(sort)
para implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
O método sort()
tem o seguinte parâmetro:
Parâmetro | Tipo | Descrição |
---|---|---|
sort | documento | Um documento que define a ordem de classificação do conjunto de resultados. |
O parâmetro sort
contém pares de campo e valor, no seguinte formato:
{ field: value }
O documento de classificação pode especificar classificação crescente ou decrescente em campos existentes ou classificação em metadados de pontuação de texto.
Comportamento
Limites
Você pode ordenar o máximo de 32 chaves.
Fornecer um padrão de classificação com campos duplicados causa um erro.
Consistência da ordenação
O MongoDB não armazena documentos em uma collection em uma ordem específica. Ao ordenar em um campo que contém valores duplicados, os documentos que contêm esses valores podem ser retornados em qualquer ordem.
Se desejar uma ordem de classificação consistente, inclua pelo menos um campo em sua ordenação que contenha valores exclusivos. A maneira mais fácil de garantir isso é incluir o campo _id
em sua query de ordenação.
Considere a seguinte collection 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"}, ] );
O seguinte comando utiliza o método sort()
para classificar no campo borough
:
db.restaurants.find().sort( { "borough": 1 } )
Neste exemplo, a ordem de classificação pode ser inconsistente, pois o campo borough
contém valores duplicados para Manhattan
e Brooklyn
. Os documentos são devolvidos em ordem alfabética por borough
, mas a ordem desses documentos com valores duplicados para borough
pode não ser a mesma em várias execuções da mesma classificação. Por exemplo, aqui estão os resultados de duas execuções diferentes do comando acima:
{ "_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" }
Embora os valores para borough
ainda estejam em ordem alfabética, a ordem dos documentos que contêm valores duplicados para borough
(ou seja, Manhattan
e Brooklyn
) não é a mesma.
Para obter uma classificação consistente, adicione um campo que contenha apenas valores exclusivos à classificação. O comando a seguir usa o método sort()
para classificar tanto o campo borough
quanto o campo _id
:
db.restaurants.find().sort( { "borough": 1, "_id": 1 } )
Como é sempre garantido que o campo _id
contenha exclusivamente valores únicos, a ordem de classificação retornada será sempre a mesma em várias execuções da mesma ordenação.
Ordem crescente/decrescente
Especifique no parâmetro de classificação o campo ou campos para classificar por e um valor de 1
ou -1
para especificar uma classificação crescente ou decrescente, respectivamente.
A operação a seguir classifica os documentos primeiro pelo campo age
em ordem decrescente e, em seguida, pelo campo posts
em ordem crescente:
db.users.find({ }).sort( { age : -1, posts: 1 } )
Ao comparar valores de diferentes tipos de BSON em operações de ordenação, o MongoDB usa a seguinte ordem de comparação, da menor para a maior:
MinKey (tipo interno)
Zero
Números (inteiros, longos, doubles, decimais)
Símbolo, string
Objeto
Array
BinData
ObjectId
Boolean
Data
Timestamp
Expressão regular
MaxKey (tipo interno)
Para obter detalhes sobre a ordem de comparação/classificação para tipos específicos, consulte Ordem de comparação/classificação.
Text Score Metadata Sort
Observação
$text
fornece recursos de query de texto para implantações autogerenciadas (não Atlas). Para dados hospedados no MongoDB Atlas, o MongoDB oferece uma solução aprimorada de query de texto completo, Atlas Search.
Se usar $text
, você pode classificar por pontuação de relevância descendente usando a expressão { $meta: "textScore" }
.
O seguinte documento de amostra especifica uma classificação decrescente pelos metadados do "textScore"
:
db.users.find( { $text: { $search: "operating" } }, { score: { $meta: "textScore" }} ).sort({ score: { $meta: "textScore" } })
Os metadados "textScore"
são classificados em ordem decrescente.
Para mais informações, consulte $meta
para detalhes.
Classificar por um Campo de Array
Quando o MongoDB classifica documentos por um campo de valor de matriz, a chave de classificação depende se a classificação é crescente ou decrescente:
Em uma classificação ascendente, a chave de classificação é o menor valor na array.
Em uma classificação decrescente, a chave de classificação é o valor mais alto na array.
O filtro de consulta não afeta a seleção da chave de classificação.
Por exemplo, crie uma coleção shoes
com estes documentos:
db.shoes.insertMany( [ { _id: 'A', sizes: [ 7, 11 ] }, { _id: 'B', sizes: [ 8, 9, 10 ] } ] )
As seguintes consultas classificam os documentos pelo campo sizes
em ordem crescente e decrescente:
// Ascending sort db.shoes.find().sort( { sizes: 1 } ) // Descending sort db.shoes.find().sort( { sizes: -1 } )
Ambas as consultas anteriores retornam o documento com _id: 'A'
primeiro porque os tamanhos 7
e 11
são o menor e o maior nas entradas na matriz sizes
, respectivamente.
A query a seguir localiza sapatos com tamanhos maiores que 10 e classifica os resultados por tamanho de sapato em ordem crescente:
db.shoes.find( { sizes: { $gte: 7 } } ).sort( { sizes: 1 } )
Essa consulta retorna o documento com _id: 'A'
primeiro, mesmo que o filtro inclua uma condição em sizes
maior que 7
porque o filtro de consulta não afeta a seleção da chave de classificação.
Uso de classificação e indexação
O MongoDB pode obter os resultados de uma operação de classificação a partir de um índice que inclui os campos de classificação. O MongoDB pode usar vários índices para oferecer suporte a uma operação de classificação se a classificação usar os mesmos índices que o predicado de query.
Se o MongoDB não puder usar um índice ou índices para obter a ordem de classificação, o MongoDB deverá executar uma operação de classificação de bloqueio nos dados. Uma classificação de bloqueio indica que o MongoDB deve consumir e processar todos os documentos de entrada para a classificação antes de retornar os resultados. As classificações de bloqueio não bloqueiam operações simultâneas na coleção ou no banco de dados.
As operações de classificação que usam um índice geralmente têm melhor desempenho do que os ordenadores bloqueantes. Para obter mais informações sobre como criar índices para dar suporte a operações de classificação, consulte Usar índices para classificar resultados de queries.
Se o MongoDB exigir o uso de mais de 100 megabytes de memória do sistema para a operação de block sort, o MongoDB retornará um erro a menos que a query especifique cursor.allowDiskUse()
. allowDiskUse()
permite que o MongoDB use arquivos temporários no disco para armazenar dados que excedam o limite de memória do sistema de 100 megabytes ao processar uma ordenador bloqueante.
Para verificar se o MongoDB deve executar uma ordenação bloqueante, acrescente cursor.explain()
à query e verifique os resultados da explicação. Se o plano de query contiver um estágio SORT
, o MongoDB deverá executar uma operação de ordenador bloqueante sujeita ao limite de memória de 100 megabytes.
Para evitar que as ordenadores bloqueantes consumam muita memória:
Crie um índice para suportar a operação de classificação. Consulte Usar índices para classificar resultados de query para obter mais informações e exemplos.
Limite a quantidade de dados para classificar utilizando
cursor.limit()
comcursor.sort()
. Consulte Limitar resultados para obter mais informações e exemplos.
Limitar resultados
Você pode utilizar sort()
em conjunto com limit()
para retornar os primeiros (em termos da ordem de classificação) k
documentos, em que k
é o limite especificado.
Se o MongoDB não conseguir obter a ordem de classificação por meio de uma varredura de índice, ele usará um algoritmo de classificação top-k. Esse algoritmo armazena os primeiros k
resultados (ou os últimos, dependendo da ordem de classificação) vistos até agora pelo índice subjacente ou acesso à coleção. Se, em algum ponto, o volume de memória desses k
resultados ultrapassar 100 megabytes, a query falhará, a menos que ela especifique cursor.allowDiskUse()
.
Interação com a projeção
Quando um conjunto de resultados é classificado e projetado, o mecanismo de query MongoDB sempre aplicará a classificação primeira.
Exemplos
Uma coleção orders
contém os seguintes documentos:
{ _id: 1, item: { category: "cake", type: "chiffon" }, amount: 10 } { _id: 2, item: { category: "cookies", type: "chocolate chip" }, amount: 50 } { _id: 3, item: { category: "cookies", type: "chocolate chip" }, amount: 15 } { _id: 4, item: { category: "cake", type: "lemon" }, amount: 30 } { _id: 5, item: { category: "cake", type: "carrot" }, amount: 20 } { _id: 6, item: { category: "brownies", type: "blondie" }, amount: 10 }
A seguinte query, que retorna todos os documentos da coleção orders
, não especifica uma ordem de classificação:
db.orders.find()
A query retorna os documentos em ordem indeterminada:
{ "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 } { "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 } { "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 } { "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 } { "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 } { "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }
A seguinte query especifica uma classificação no campo amount
em ordem decrescente.
db.orders.find().sort( { amount: -1 } )
A query retorna os seguintes documentos, em ordem decrescente de amount
:
{ "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 } { "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 } { "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 } { "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 } { "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 } { "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 }
A query a seguir especifica a ordem de classificação usando os campos de um documento incorporado item
. A query classifica primeiro pelo campo category
em ordem crescente e, em seguida, dentro de cada category
, pelo campo type
em ordem crescente.
db.orders.find().sort( { "item.category": 1, "item.type": 1 } )
A query retorna os seguintes documentos, ordenados primeiro pelo campo category
e dentro de cada categoria, pelo campo type
:
{ "_id" : 6, "item" : { "category" : "brownies", "type" : "blondie" }, "amount" : 10 } { "_id" : 5, "item" : { "category" : "cake", "type" : "carrot" }, "amount" : 20 } { "_id" : 1, "item" : { "category" : "cake", "type" : "chiffon" }, "amount" : 10 } { "_id" : 4, "item" : { "category" : "cake", "type" : "lemon" }, "amount" : 30 } { "_id" : 2, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 50 } { "_id" : 3, "item" : { "category" : "cookies", "type" : "chocolate chip" }, "amount" : 15 }
Retorno em ordem natural
O parâmetro $natural
retorna itens de acordo com sua ordem natural dentro do banco de dados. Este pedido é um recurso de implementação interna, e você não deve confiar em nenhum pedido específico dos documentos.
Uso do índice
Queries que incluem uma classificação por $natural
pedido não usam índices para preencher o predicado de consulta com a seguinte exceção: Se o predicado de consulta for uma condição de igualdade no _id
campo { _id: <value> }
, então a consulta com a ordem de classificação por $natural
pode usar o índice _id
.