Agregação
Nesta página
Visão geral
Neste guia, você pode aprender como usar as operações de agregação no driver Java MongoDB.
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.
Agregação e encontrar operações comparadas
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 algumas limitaçõ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
.
Referências úteis
Exemplos executáveis
Configuração da Base
Crie um novo arquivo Java denominado AggTour.java
e inclua as seguintes declarações de importação:
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.ExplainVerbosity; import com.mongodb.client.model.Accumulators; import com.mongodb.client.model.Aggregates; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Projections; import org.bson.Document; import java.util.Arrays; import java.util.List;
Conecte-se a um MongoDB deployment
public class AggTour { public static void main(String[] args) { // Replace the uri string with your MongoDB deployment's connection string String uri = "<connection string uri>"; MongoClient mongoClient = MongoClients.create(uri); MongoDatabase database = mongoClient.getDatabase("aggregation"); MongoCollection<Document> collection = database.getCollection("restaurants"); // aggregation here } }
Dica
Veja também:
Para obter informações sobre como se conectar ao MongoDB, consulte o Guia de conexão
Insira os dados
collection.insertMany(Arrays.asList( new Document("name", "Sun Bakery Trattoria").append("contact", new Document().append("phone", "386-555-0189").append("email", "SunBakeryTrattoria@example.org").append("location", Arrays.asList(-74.0056649, 40.7452371))).append("stars", 4).append("categories", Arrays.asList("Pizza", "Pasta", "Italian", "Coffee", "Sandwiches")), new Document("name", "Blue Bagels Grill").append("contact", new Document().append("phone", "786-555-0102").append("email", "BlueBagelsGrill@example.com").append("location", Arrays.asList(-73.92506, 40.8275556))).append("stars", 3).append("categories", Arrays.asList("Bagels", "Cookies", "Sandwiches")), new Document("name", "XYZ Bagels Restaurant").append("contact", new Document().append("phone", "435-555-0190").append("email", "XYZBagelsRestaurant@example.net").append("location", Arrays.asList(-74.0707363, 40.59321569999999))).append("stars", 4).append("categories", Arrays.asList("Bagels", "Sandwiches", "Coffee")), new Document("name", "Hot Bakery Cafe").append("contact", new Document().append("phone", "264-555-0171").append("email", "HotBakeryCafe@example.net").append("location", Arrays.asList(-73.96485799999999, 40.761899))).append("stars", 4).append("categories", Arrays.asList("Bakery", "Cafe", "Coffee", "Dessert")), new Document("name", "Green Feast Pizzeria").append("contact", new Document().append("phone", "840-555-0102").append("email", "GreenFeastPizzeria@example.com").append("location", Arrays.asList(-74.1220973, 40.6129407))).append("stars", 2).append("categories", Arrays.asList("Pizza", "Italian")), new Document("name", "ZZZ Pasta Buffet").append("contact", new Document().append("phone", "769-555-0152").append("email", "ZZZPastaBuffet@example.com").append("location", Arrays.asList(-73.9446421, 40.7253944))).append("stars", 0).append("categories", Arrays.asList("Pasta", "Italian", "Buffet", "Cafeteria")), new Document("name", "XYZ Coffee Bar").append("contact", new Document().append("phone", "644-555-0193").append("email", "XYZCoffeeBar@example.net").append("location", Arrays.asList(-74.0166091, 40.6284767))).append("stars", 5).append("categories", Arrays.asList("Coffee", "Cafe", "Bakery", "Chocolates")), new Document("name", "456 Steak Restaurant").append("contact", new Document().append("phone", "990-555-0165").append("email", "456SteakRestaurant@example.com").append("location", Arrays.asList(-73.9365108, 40.8497077))).append("stars", 0).append("categories", Arrays.asList("Steak", "Seafood")), new Document("name", "456 Cookies Shop").append("contact", new Document().append("phone", "604-555-0149").append("email", "456CookiesShop@example.org").append("location", Arrays.asList(-73.8850023, 40.7494272))).append("stars", 4).append("categories", Arrays.asList("Bakery", "Cookies", "Cake", "Coffee")), new Document("name", "XYZ Steak Buffet").append("contact", new Document().append("phone", "229-555-0197").append("email", "XYZSteakBuffet@example.org").append("location", Arrays.asList(-73.9799932, 40.7660886))).append("stars", 3).append("categories", Arrays.asList("Steak", "Salad", "Chinese")) ));
Exemplo de aggregation básica
Para executar uma agregação, passe uma lista de estágios de agregação para o método MongoCollection.aggregate()
.
O driver Java fornece a classe auxiliar Agregados 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 elementoBakery
. O exemplo usaAggregates.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 destars
.
Dica
Veja também:
Você pode construir as expressões utilizadas neste exemplo utilizando os construtores de agregação.
collection.aggregate( Arrays.asList( Aggregates.match(Filters.eq("categories", "Bakery")), Aggregates.group("$stars", Accumulators.sum("count", 1)) ) // Prints the result of the aggregation operation as JSON ).forEach(doc -> System.out.println(doc.toJson()));
A aggregation anterior deve produzir os seguintes resultados:
{"_id": 4, "count": 2} {"_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:
Explicar exemplo de aggregation
Para visualizar informações sobre como o MongoDB executa sua operação, utilize o método explain()
da classe AggregateIterable
. 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:
Document explanation = collection.aggregate( Arrays.asList( Aggregates.match(Filters.eq("categories", "Bakery")), Aggregates.group("$stars", Accumulators.sum("count", 1)) ) ).explain(ExplainVerbosity.EXECUTION_STATS); List<Document> stages = explanation.get("stages", List.class); List<String> keys = Arrays.asList("queryPlanner", "winningPlan"); // Prints the JSON representation of the winning execution plans for (Document stage : stages) { Document cursorStage = stage.get("$cursor", Document.class); if (cursorStage != null) { System.out.println(cursorStage.getEmbedded(keys, Document.class).toJson()); } }
O trecho de código anterior deve produzir o seguinte resultado:
{ "stage": "PROJECTION_SIMPLE", "transformBy": {"stars": 1, "_id": 0}, "inputStage": { "stage": "COLLSCAN", "filter": { "categories": {"$eq":"bakery"}}, "direction": "forward"}}
Para obter mais informações sobre os tópicos mencionados nesta seção, consulte os seguintes recursos:
Explicar saída Entrada manual do servidor
Planos de query Entrada manual do servidor
Explicar verbosidade Documentação da API
explain() Documentação da API
Documentação da API AggregateIterable
Exemplo de expressão de aggregation
O driver Java fornece construtores para expressões de acumuladors 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.
new Document("$arrayElemAt", Arrays.asList("$categories", 0))
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
.
collection.aggregate( Arrays.asList( Aggregates.project( Projections.fields( Projections.excludeId(), Projections.include("name"), Projections.computed( "firstCategory", new Document("$arrayElemAt", Arrays.asList("$categories", 0)) ) ) ) ) ).forEach(doc -> System.out.println(doc.toJson()));
A aggregation anterior deve produzir os seguintes resultados:
{"name": "456 Cookies Shop", "firstCategory": "Bakery"} {"name": "Sun Bakery Trattoria", "firstCategory": "Pizza"} {"name": "456 Steak Restaurant", "firstCategory": "Steak"} {"name": "Blue Bagels Grill", "firstCategory": "Bagels"} {"name": "XYZ Steak Buffet", "firstCategory": "Steak"} {"name": "Hot Bakery Cafe", "firstCategory": "Bakery"} {"name": "Green Feast Pizzeria", "firstCategory": "Pizza"} {"name": "ZZZ Pasta Buffet", "firstCategory": "Pasta"} {"name": "XYZ Coffee Bar", "firstCategory": "Coffee"} {"name": "XYZ Bagels Restaurant", "firstCategory": "Bagels"}
Para obter mais informações sobre os métodos e as classes mencionadas nesta seção, consulte a seguinte documentação da API: