Menu Docs
Página inicial do Docs
/ / /
Kotlin Coroutine
/ / /

Classificar resultados

Nesta página

  • Visão geral
  • Métodos de classificação
  • Direção de classificação
  • Ascendente
  • Descendente
  • Lidar com empates
  • Combinando critérios de classificação
  • Pesquisa de texto

Neste guia, você pode aprender como usar operações de classificação para ordenar seus resultados de operações de leitura com o driver MongoDB Kotlin.

A operação de classificação ordena os documentos retornados da sua query de acordo com os critérios de classificação especificados. Os critérios de classificação são as regras que você passa para o MongoDB e descrevem como você gostaria que seus dados fossem ordenados. Alguns exemplos de critérios de classificação são:

  • Do menor número para o maior número

  • Hora do dia mais antiga para a última hora do dia

  • Ordem alfabética pelo nome

Leia este guia para saber como executar as seguintes ações:

  • Executar classificações crescentes e classificações decrescentes

  • Combinar critérios de classificação

  • Classificar na pontuação de texto de um Atlas Search

Os exemplos deste guia usam uma collection de amostras que contém os seguintes documentos:

{ "_id": 1, "date": "2022-01-03", "orderTotal": 17.86, "description": "1/2 lb cream cheese and 1 dozen bagels" },
{ "_id": 2, "date": "2022-01-11", "orderTotal": 83.87, "description": "two medium vanilla birthday cakes" },
{ "_id": 3, "date": "2022-01-11", "orderTotal": 19.49, "description": "1 dozen vanilla cupcakes" },
{ "_id": 4, "date": "2022-01-15", "orderTotal": 43.62, "description": "2 chicken lunches and a diet coke" },
{ "_id": 5, "date": "2022-01-23", "orderTotal": 60.31, "description": "one large vanilla and chocolate cake" },
{ "_id": 6, "date": "2022-01-23", "orderTotal": 10.99, "description": "1 bagel, 1 orange juice, 1 muffin" }

Esses dados são modelados com a seguinte classe de dados Kotlin:

data class Order(
@BsonId val id: Int,
val date: String,
val orderTotal: Double,
val description: String,
)

Você pode classificar os resultados recuperados por uma query ou classificar os resultados dentro de uma aggregation pipeline.

Para classificar seus resultados de query, utilize o método sort() de uma instância do FindFlow . Para classificar seus resultados dentro de um pipeline de agregação, utilize o método de fábrica estático do Aggregates.sort() . Ambos os métodos recebem objetos que implementam a interface Bson como argumentos. Para obter mais informações, consulte a documentação da API para a interface BSON.

Você pode utilizar o método sort() de uma instância do FindFlow como segue:

val resultsFlow = collection.find().sort(Sorts.ascending(Order::orderTotal.name))

Você pode usar o método Aggregates.sort() em um aggregation pipeline para classificar os documentos na coleção de amostras do menor para o maior valor do campo orderTotal da seguinte forma:

val resultsFlow = collection.aggregate(listOf(
Aggregates.sort(Sorts.ascending(Order::orderTotal.name))
))
resultsFlow.collect { println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)
Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes)
Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke)
Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)

Nos trechos de código anteriores, especificamos os critérios de classificação usando a classe de construtor Sorts . Embora seja possível especificar critérios de classificação usando qualquer classe que implemente a interface Bson , recomendamos que você especifique os critérios de classificação por meio do construtor Sorts . Para obter mais informações sobre a classe de construtor Sorts , consulte o guia de construtor Sort .

Para obter mais informações sobre as classes e interfaces nesta seção, consulte a seguinte Documentação da API:

A direção da sua classificação pode ser ascendente ou descendente. Uma classificação crescente ordena seus resultados do menor para o maior. Uma classificação decrescente ordena seus resultados do maior para o menor.

Aqui estão alguns exemplos de dados classificados em ordem crescente:

  • Números: 1, 2, 3, 43, 43, 55, 120

  • Datas: 10/03/1990, 01/1995, 30/10/2005, 21/12/2005

  • Palavras (ASCII): Banana, endro, cenoura, pepino, homus

Aqui estão alguns exemplos de dados classificados em ordem decrescente:

  • Números: 100, 30, 12, 12, 9, 3, 1

  • Datas: 01/2020, 11/12/1998, 10/12/1998, 22/07/1975

  • Palavras (ASCII reverso): pêra, Uva, Maçã, Queque

As subseções a seguir mostram como especificar esses critérios de classificação.

Para especificar uma classificação crescente, utilize o método de fábrica estática Sorts.ascending() . Passe o método Sorts.ascending() o nome do campo que você precisa classificar em ordem crescente.

Você pode passar o método sort() para a saída do método Sorts.ascending() para especificar uma classificação ascendente em um campo da seguinte forma:

collection.find().sort(Sorts.ascending("<field name>"))

O método sort() anterior retorna um objeto FindIterable que pode iterar sobre os documentos em sua coleção, classificados do menor para o maior no nome de campo especificado.

No exemplo de código a seguir, usamos o método ascending() para classificar a coleção de amostras pelo campo orderTotal :

val resultsFlow = collection.find()
.sort(Sorts.ascending(Order::orderTotal.name))
resultsFlow.collect { println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)
Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes)
Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke)
Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)

Para especificar uma classificação decrescente, use o método de fábrica estática Sorts.descending() . Passe o método Sorts.descending() o nome do campo que você precisa classificar em ordem decrescente.

O seguinte trecho de código mostra como especificar uma classificação decrescente no campo orderTotal e retornar os documentos na coleção de amostra em ordem decrescente:

val resultsFlow = collection.find()
.sort(Sorts.descending(Order::orderTotal.name))
resultsFlow.collect { println(it) }
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)
Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)
Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke)
Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes)
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)

Um empate ocorre quando dois ou mais documentos têm valores idênticos no campo que você está usando para ordenar seus resultados. O MongoDB não garante a ordem de classificação em caso de empate. Por exemplo, suponha que encontremos um empate ao aplicar uma classificação à coleção de amostras usando o código a seguir:

collection.find().sort(Sorts.ascending(Order::date.name))

Como vários documentos que corresponderam à query contêm o mesmo valor no campo date , os documentos podem não ser retornados em uma ordem consistente.

Se você precisar garantir uma ordem específica para documento que tenham campo com valores idênticos, poderá especificar campo adicionais para ordenar em evento de empate.

Podemos especificar uma classificação ascendente no campo date seguido pelo campo orderTotal para retornar os documentos na coleção de amostra na seguinte ordem:

collection.find().sort(Sorts.ascending(Order::date.name, Order::orderTotal.name))
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)
Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes)
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)
Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke)
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)
Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)

Para combinar critérios de classificação, use o método de fábrica estática Sorts.orderBy() . Este método constrói um objeto contendo uma lista ordenada de critérios de classificação. Ao executar a classificação, se os critérios de classificação anteriores resultarem em um empate, a classificação utilizará os próximos critérios de classificação na lista para determinar a ordem.

No trecho de código a seguir, usamos o método orderBy() para ordenar os dados executando uma classificação descendente no campo date e, no caso de um empate, executando uma classificação ascendente no campo orderTotal . Com esses critérios de classificação, o código retorna os documentos na coleção de amostra na seguinte ordem:

val orderBySort = Sorts.orderBy(
Sorts.descending(Order::date.name), Sorts.ascending(Order::orderTotal.name)
)
val results = collection.find().sort(orderBySort)
results.collect {println(it) }
Order(id=6, date=2022-01-23, orderTotal=10.99, description=1 bagel, 1 orange juice, 1 muffin)
Order(id=5, date=2022-01-23, orderTotal=60.31, description=one large vanilla and chocolate cake)
Order(id=4, date=2022-01-15, orderTotal=43.62, description=2 chicken lunches and a diet coke)
Order(id=3, date=2022-01-11, orderTotal=19.49, description=1 dozen vanilla cupcakes)
Order(id=2, date=2022-01-11, orderTotal=83.87, description=two medium vanilla birthday cakes)
Order(id=1, date=2022-01-03, orderTotal=17.86, description=1/2 lb cream cheese and 1 dozen bagels)

Você pode especificar a ordem dos resultados de uma de texto Atlas Search considerando a proximidade dos string valores de de cada campo de resultado especificados pelo índice de texto da coleção à sua Atlas Search string do . O texto do Atlas Search atribui uma pontuação numérica de texto para indicar até que ponto cada resultado corresponde à Atlas Search string do . Use o método de fábrica estática Sorts.metaTextScore() para criar seus critérios de classificação para classificar pela pontuação de texto.

Importante

Certifique-se de criar um índice de texto

Você precisa de um índice de texto em sua collection para executar uma Atlas Search de texto . Consulte a documentação do manual do servidor para obter mais informações sobre como criar um índice de texto.

No exemplo de código a seguir, mostramos como você pode usar o método Sorts.metaTextScore() para classificar os resultados de um Atlas Search de texto na coleção de amostras. O exemplo de código utiliza os construtores Filtros, Índices e Projeções .

O exemplo de código executa a seguinte ação:

  1. Cria um índice de texto para sua coleção de amostra no campo description . Se você chamar createIndex() especificando um índice que já existe na coleção, a operação não criará um novo índice.

  2. Executa sua pesquisa de texto para a frase "vanilla".

  3. Projeta pontuações de texto em seus resultados de query como o campo score .

  4. Classifica seus resultados por pontuação de texto (primeira correspondência).

Os dados são modelados com a seguinte classe de dados Kotlin:

data class OrderScore(
@BsonId val id: Int,
val description: String,
val score: Double
)
import com.mongodb.client.model.Sorts
import com.mongodb.client.model.Projections
import com.mongodb.client.model.Filters
import com.mongodb.client.model.Indexes
collection.createIndex(Indexes.text(Order::description.name))
val metaTextScoreSort = Sorts.orderBy(
Sorts.metaTextScore(OrderScore::score.name),
Sorts.descending("_id")
)
val metaTextScoreProj = Projections.metaTextScore(OrderScore::score.name)
val searchTerm = "vanilla"
val searchQuery = Filters.text(searchTerm)
val results = collection.find<OrderScore>(searchQuery)
.projection(metaTextScoreProj)
.sort(metaTextScoreSort)
results.collect { println(it) }
OrderScore(id=3, description=1 dozen vanilla cupcakes, score=0.625)
OrderScore(id=5, description=one large vanilla and chocolate cake, score=0.6)
OrderScore(id=2, description=two medium vanilla birthday cakes, score=0.6)

Observação

Comportamento do Atlas Search por texto no MongoDB 4.4 ou posterior

A estrutura da pesquisa de texto foi alterada para MongoDB 4.4 ou posterior. Você não precisa mais projetar Projections.metaTextScore() na sua instância FindFlow para ordenar na pontuação do texto. Além disso, o nome do campo especificado em uma operação de agregação de pontuação de texto $meta usada em uma classificação é ignorado. Isso significa que o argumento do nome do campo que você passa para Sorts.metaTextScore() é desconsiderado.

Para obter mais informações sobre as aulas nesta seção, consulte a seguinte documentação da API:

Para obter mais informações, consulte a classe Classificações Documentação da API. Consulte a documentação manual do servidor para obter mais informações sobre o operador de query $text e o operador de pipeline de agregação $meta .

Voltar

Fluxos de change streams

Próximo

Ignorar resultados devolvidos