Definição
Compatibilidade
Você pode utilizar o $sort para implantações hospedadas nos seguintes ambientes:
- MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
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
The $sort stage has the following prototype form:
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
$sort takes a document that specifies the field(s) to sort by and the respective sort order. <sort order> can have one of the following values:
Valor | Descrição |
|---|---|
| Ordem crescente. |
| Ordem decrescente. |
|
|
Se estiver ordenando em vários campos, a ordem de classificação será avaliada da esquerda para a direita. Por exemplo, no formato acima, os documentos são ordenados pela primeira vez por <field1>. Em seguida, os documentos com os mesmos valores <field1> são ordenados por <field2>.
Comportamento
Desempenho
$sort é um estágio de bloqueio, que faz com que o pipeline espere que todos os dados de entrada sejam recuperados para o estágio de bloqueio antes de processar os dados. Um estágio de bloqueio pode reduzir o desempenho porque reduz o processamento paralelo de um pipeline com vários estágios. Um estágio de bloqueio também pode usar quantidades substanciais de memória para grandes conjuntos de dados.
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"}, ] )
The following command uses the $sort stage to sort on the borough field:
db.restaurants.aggregate( [ { $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 retornados 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 ordenaçã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.
To achieve a consistent sort, add a field which contains exclusively unique values to the sort. The following command uses the $sort stage to sort on both the borough field and the _id field:
db.restaurants.aggregate( [ { $sort : { borough : 1, _id: 1 } } ] )
Como o campo _id sempre garante conter exclusivamente valores únicos, a ordem de classificação retornada é sempre a mesma em várias execuções da mesma classificação.
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.aggregate( [ { $sort: { sizes: 1 } } ] ) // Descending sort db.shoes.aggregate( [ { $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.
Filtrar e ordenar por um campo de Array
Quando você filtra e ordena por um campo que contém um array, o filtro não altera o valor utilizado como chave de ordenação. A ordenação sempre considera todos os valores do array como possíveis chaves de ordenação.
Por exemplo, a query a seguir encontra sapatos com tamanhos maiores que 9 e ordena os resultados por tamanho em ordem crescente:
db.shoes.aggregate( [ { $match: { sizes: { $gt: 9 } } }, { $sort: { sizes: 1 } } ] )
A classificação é ascendente, o que significa que a chave de classificação é o menor valor na array sizes:
No documento
_id: 'A', o elementosizesde menor valor é7. Este valor é utilizado como chave de ordenação, mesmo que não corresponda ao filtro{ sizes: { $gt: 9 }.No documento
_id: 'B', o elementosizesde menor valor é8. Da mesma forma, este valor é utilizado como chave de ordenação, mesmo que não corresponda ao filtro.
A consulta retorna o documento com _id: 'A' primeiro.
Dica
Ordenar somente por valores correspondentes
Para considerar apenas os valores correspondentes como chaves de ordenação potenciais, você pode criar um novo campo contendo esses valores e ordenar com base nesse campo. Para obter mais informações, consulte estes estágios e expressões do pipeline:
$sort Operador e memória
$sort + $limit Otimização de memória
When a $sort precedes a $limit and there are no intervening stages that modify the number of documents, the optimizer can coalesce the $limit into the $sort. This allows the $sort operation to only maintain the top n results as it progresses, where n is the specified limit, and ensures that MongoDB only needs to store n items in memory. This optimization still applies when allowDiskUse is true and the n items exceed the aggregation memory limit.
As otimizações estão sujeitas a alterações entre as versões.
$sort e restrições de memória
A partir do MongoDB 6.0, os estágios do pipeline que exigem mais de 100 megabytes de memória para execução gravam arquivos temporários no disco por padrão. Esses arquivos temporários duram durante a execução do pipeline e podem influenciar o espaço de armazenamento na sua instância. Em versões anteriores do MongoDB, você deve passar { allowDiskUse: true } para find individuais e comandos aggregate para habilitar esse comportamento.
Somente find e aggregate comandos podem substituir o parâmetro allowDiskUseByDefault por um ou outro:
Usando
{ allowDiskUse: true }para permitir a gravação de arquivos temporários no disco quandoallowDiskUseByDefaultestiver definido comofalseUsando
{ allowDiskUse: false }para proibir a gravação de arquivos temporários no disco quandoallowDiskUseByDefaultestiver definido comotrue
Observação
For MongoDB Atlas, it is recommended to configure storage auto-scaling to prevent long-running queries from filling up storage with temporary files.
Se o Atlas cluster usar auto-scaling de armazenamento, os arquivos temporários podem fazer com que o cluster seja dimensionado para o próximo nível de armazenamento.
Para obter mais detalhes, consulte Limites do pipeline de agregação.
$sort Operador e desempenho
The $sort operator can take advantage of an index if it's used in the first stage of a pipeline or if it's only preceded by a $match stage.
Quando você usa $sort em uma coleção sharded, cada shard ordena seus documentos de resultado usando um índice, quando disponível. Em seguida, mongos ou um dos shards executa uma ordenação de mesclagem transmitida.
Exemplos
Ordem crescente/decrescente
Para o campo ou campos a serem ordenados, defina a ordem de classificação como 1 ou -1 para especificar uma classificação crescente ou decrescente, respectivamente, como no exemplo a seguir:
db.users.aggregate( [ { $sort : { age : -1, posts: 1 } } ] )
Esta operação coloca os documentos na collection users em ordem decrescente, de acordo com o campo age, e, em seguida, em ordem crescente, de acordo com o valor no campo posts.
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
Código JavaScript
JavaScript code with scope
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 provides text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB Atlas, MongoDB offers an improved full-text query solution, Atlas Search.
Para um pipeline que inclui $text, você pode ordenar por pontuação de relevância decrescente usando a expressão { $meta: "textScore" }. No documento { <sort-key> }, configure a expressão { $meta: "textScore" } para um nome de campo arbitrário. O nome do campo é ignorado pelo sistema de query. Por exemplo:
db.users.aggregate( [ { $match: { $text: { $search: "operating" } } }, { $sort: { score: { $meta: "textScore" }, posts: -1 } } ] )
Esta operação usa o operador $text para fazer a correspondência entre os documentos e, em seguida, ordena primeiro pelos metadados "textScore" em ordem decrescente e, depois, pelo campo posts em ordem decrescente. O nome do campo score no documento de ordenação é ignorado pelo sistema de query. Neste pipeline, os metadados "textScore" não são incluídos na projeção e não são retornados como parte dos documentos correspondentes. Consulte $meta para mais informações.
Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.
A seguinte classe Movie modela os documentos na collection sample_mflix.movies:
[] public class Movie { [] public ObjectId Id { get; set; } [] public string Title { get; set; } = null!; [] public int? Year { get; set; } [] public int? Runtime { get; set; } [] public string? Rated { get; set; } [] public int Metacritic { get; set; } [] public string? Plot { get; set; } [] public string? Type { get; set; } [] public string[]? Cast { get; set; } [] public string[]? Directors { get; set; } [] public string[]? Writers { get; set; } [] public ImdbData? Imdb { get; set; } }
Para usar o driver MongoDB .NET/C# para adicionar um estágio $sort a uma agregação pipeline, chame o método UnionWith() em um objeto PipelineDefinition.
O exemplo a seguir cria um estágio de pipeline que primeiro filtra os documentos Movie onde Metacritic é igual a 100, em seguida, classifica os resultados em ordem decrescente pelo campo Year e em ordem crescente pelo campo Title:
var pipeline = new EmptyPipelineDefinition<Movie>() .Match(Builders<Movie>.Filter.Eq(m => m.Metacritic, 100)) .Sort(Builders<Movie>.Sort.Combine( Builders<Movie>.Sort.Descending(m => m.Year), Builders<Movie>.Sort.Ascending(m => m.Title)));
Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js
Para usar o driver Node.js do MongoDB para adicionar um estágio $sort a um pipeline de agregação , use o operador $sort em um objeto de pipeline.
O exemplo a seguir cria uma etapa de pipeline que ordena os documentos de entrada movie primeiro em ordem decrescente pelo campo year e depois em ordem crescente pelo campo title. O exemplo em seguida executa o pipeline de agregação:
const pipeline = [{ $sort: { year: -1, title: 1 } }]; const cursor = collection.aggregate(pipeline); return cursor;
Saiba mais
To see full aggregation examples that use the $sort stage, see the Complete Aggregation Pipeline Tutorials.