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

Agregação

Nesta página

  • Visão geral
  • Agregação e encontrar operações comparadas
  • Referências úteis
  • Dados de exemplo
  • aggregation básica
  • Explicar agregação
  • expressão de agregação

Neste guia, você pode aprender como usar as operações de agregação no driver MongoDB Kotlin.

Operações de agregação processam dados em suas coleções MongoDB e retornam resultados calculados. O pipeline de agregação do MongoDB, parte da API de queries, é modelado sobre o conceito de pipelines de processamento de dados. Os documentos entram em um pipeline em várias etapas que transforma os documentos em um resultado agregado.

Outra forma de pensar em agregação é como uma fábrica de automóveis. Dentro da fábrica de automóveis há uma linha de montagem, ao longo da qual há estações de montagem com ferramentas especializadas para fazer uma tarefa específica, como furadeiras e soldadores. As peças entram na fábrica, que então são transformadas e montadas em um produto acabado.

O pipeline de agregação é a linha de montagem, estágios de agregação são as estações de montagem e expressões do operador são as ferramentas especializadas.

Usando operações find , você pode:

  • Selecione quais documentos devolver

  • Selecione quais campos devem ser devolvidos

  • ordenar os resultados

Usando operações aggregation , você pode:

  • realizar todas as operações find

  • Renomear campos

  • Calcular campos

  • Resumir dados

  • Agrupar valores

As operações de agregação têm algumaslimitações que você deve ter em mente:

  • Os documentos retornados não devem violar o limite de tamanho do documento BSON de 16 megabytes.

  • Os estágios do pipeline têm um limite de memória de 100 megabytes por padrão. Se necessário, você pode exceder esse limite com o método allowDiskUse.

    Importante

    exceção $graphLookup

    O estágio $graphLookup tem um limite de memória rigoroso de 100 megabytes e ignorará allowDiskUse.

  • Pipeline de agregação

  • Estágios de agregação

  • Expressões do operador

  • Construtores de aggregations

Os exemplos utilizam uma collection dos seguintes dados no MongoDB:

[
{"name": "Sun Bakery Trattoria", "contact": {"phone": "386-555-0189", "email": "SunBakeryTrattoria@example.org", "location": [-74.0056649, 40.7452371]}, "stars": 4, "categories": ["Pizza", "Pasta", "Italian", "Coffee", "Sandwiches"]},
{"name": "Blue Bagels Grill", "contact": {"phone": "786-555-0102", "email": "BlueBagelsGrill@example.com", "location": [-73.92506, 40.8275556]}, "stars": 3, "categories": ["Bagels", "Cookies", "Sandwiches"]},
{"name": "XYZ Bagels Restaurant", "contact": {"phone": "435-555-0190", "email": "XYZBagelsRestaurant@example.net", "location": [-74.0707363, 40.59321569999999]}, "stars": 4, "categories": ["Bagels", "Sandwiches", "Coffee"]},
{"name": "Hot Bakery Cafe", "contact": {"phone": "264-555-0171", "email": "HotBakeryCafe@example.net", "location": [-73.96485799999999, 40.761899]}, "stars": 4, "categories": ["Bakery", "Cafe", "Coffee", "Dessert"]},
{"name": "Green Feast Pizzeria", "contact": {"phone": "840-555-0102", "email": "GreenFeastPizzeria@example.com", "location": [-74.1220973, 40.6129407]}, "stars": 2, "categories": ["Pizza", "Italian"]},
{"name": "ZZZ Pasta Buffet", "contact": {"phone": "769-555-0152", "email": "ZZZPastaBuffet@example.com", "location": [-73.9446421, 40.7253944]}, "stars": 0, "categories": ["Pasta", "Italian", "Buffet", "Cafeteria"]},
{"name": "XYZ Coffee Bar", "contact": {"phone": "644-555-0193", "email": "XYZCoffeeBar@example.net", "location": [-74.0166091, 40.6284767]}, "stars": 5, "categories": ["Coffee", "Cafe", "Bakery", "Chocolates"]},
{"name": "456 Steak Restaurant", "contact": {"phone": "990-555-0165", "email": "456SteakRestaurant@example.com", "location": [-73.9365108, 40.8497077]}, "stars": 0, "categories": ["Steak", "Seafood"]},
{"name": "456 Cookies Shop", "contact": {"phone": "604-555-0149", "email": "456CookiesShop@example.org", "location": [-73.8850023, 40.7494272]}, "stars": 4, "categories": ["Bakery", "Cookies", "Cake", "Coffee"]},
{"name": "XYZ Steak Buffet", "contact": {"phone": "229-555-0197", "email": "XYZSteakBuffet@example.org", "location": [-73.9799932, 40.7660886]}, "stars": 3, "categories": ["Steak", "Salad", "Chinese"]}
]

Os dados na collection são modelados pela seguinte classe de dados Restaurant :

data class Restaurant(
val name: String,
val contact: Contact,
val stars: Int,
val categories: List<String>
) {
data class Contact(
val phone: String,
val email: String,
val location: List<Double>
)
}

Para executar uma agregação, passe uma lista de estágios de agregação para o método MongoCollection.aggregate().

O driver Kotlin fornece aos Agregados classe auxiliar que contém construtores para estágios de agregação.

No exemplo a seguir, o aggregation pipeline:

  • Usa um estágio $match para filtrar os documentos cujo campo de array categories contém o elemento Bakery. O exemplo usa Aggregates.match para criar o estágio $match.

  • Utiliza um estágio $group para agrupar os documentos correspondentes pelo campo stars, acumulando uma contagem de documentos para cada valor distinto de stars.

Dica

Veja também:

Você pode construir as expressões utilizadas neste exemplo utilizando os construtores de agregação.

data class Results(@BsonId val id: Int, val count: Int)
val resultsFlow = collection.aggregate<Results>(
listOf(
Aggregates.match(Filters.eq(Restaurant::categories.name, "Bakery")),
Aggregates.group("\$${Restaurant::stars.name}",
Accumulators.sum("count", 1))
)
)
resultsFlow.collect { println(it) }
Results(id=4, count=2)
Results(id=5, count=1)

Para obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:

Para visualizar informações sobre como o MongoDB executa sua operação, utilize o método explain() da classe AggregateFlow. O método explain() retorna planos de execução e estatísticas de desempenho. Um plano de execução é uma maneira em potencial de o MongoDB concluir uma operação. O método explain() fornece tanto o plano vencedor (o plano que o MongoDB executou) quanto os planos rejeitados.

Você pode especificar o nível de detalhes da sua explicação passando um nível de detalhamento para o método explain().

A tabela a seguir mostra todos os níveis de detalhamento para explicações e seus casos de uso pretendidos:

Nível de verbosidade
Caso de uso

ALL_PLANS_EXECUTIONS

Você deseja saber qual plano o MongoDB escolherá para executar sua query.

EXECUTION_STATS

Você quer saber se sua query está tendo um bom desempenho.

QUERY_PLANNER

Você tem um problema com sua query e deseja o máximo de informações possível para diagnosticar o problema.

No exemplo a seguir, imprimimos a representação JSON dos planos vencedores para estágios de agregação que produzem planos de execução:

data class Results (val name: String, val count: Int)
val explanation = collection.aggregate<Results>(
listOf(
Aggregates.match(Filters.eq(Restaurant::categories.name, "bakery")),
Aggregates.group("\$${Restaurant::stars.name}", Accumulators.sum("count", 1))
)
).explain(ExplainVerbosity.EXECUTION_STATS)
// Prettyprint the output
println(explanation.toJson(JsonWriterSettings.builder().indent(true).build()))
{
"explainVersion": "2",
"queryPlanner": {
// ...
},
"command": {
// ...
},
// ...
}

Para obter mais informações sobre os tópicos mencionados nesta seção, consulte os seguintes recursos:

O driver Kotlin fornece construtores para expressões de acumulador para utilizar com $group. Você deve declarar todas as outras expressões no formato JSON ou formato de documento compatível.

Dica

A sintaxe em qualquer um dos exemplos a seguir definirá uma expressão $arrayElemAt.

O $ na frente de "categories" informa ao MongoDB que este é um caminho de campo, usando o campo "categorias" do documento de entrada.

Document("\$arrayElemAt", listOf("\$categories", 0))
// is equivalent to
Document.parse("{ \$arrayElemAt: ['\$categories', 0] }")

No exemplo a seguir, o aggregation pipeline usa um estágio $project e várias Projections para retornar o campo name e o campo calculado firstCategory cujo valor é o primeiro elemento no campo categories.

data class Results(val name: String, val firstCategory: String)
val resultsFlow = collection.aggregate<Results>(
listOf(
Aggregates.project(
Projections.fields(
Projections.excludeId(),
Projections.include("name"),
Projections.computed(
"firstCategory",
Document("\$arrayElemAt", listOf("\$categories", 0))
)
)
)
)
)
resultsFlow.collect { println(it) }
Results(name=Sun Bakery Trattoria, firstCategory=Pizza)
Results(name=Blue Bagels Grill, firstCategory=Bagels)
Results(name=XYZ Bagels Restaurant, firstCategory=Bagels)
Results(name=Hot Bakery Cafe, firstCategory=Bakery)
Results(name=Green Feast Pizzeria, firstCategory=Pizza)
Results(name=ZZZ Pasta Buffet, firstCategory=Pasta)
Results(name=XYZ Coffee Bar, firstCategory=Coffee)
Results(name=456 Steak Restaurant, firstCategory=Steak)
Results(name=456 Cookies Shop, firstCategory=Bakery)
Results(name=XYZ Steak Buffet, firstCategory=Steak)

Para obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API:

Voltar

Construtores e classes de dados