Visão geral
Neste guia, veja como usar a classe Agregados que fornece métodos estáticos de fábrica para construir aggregation pipeline stages no driver Java do MongoDB.
Para saber mais sobre a aggregation, consulte nosso Guia de aggregation. Para saber como criar operações de expressão com métodos Java detectáveis e seguros para usar em suas aggregations, consulte Operações de expressão de aggregation.
Dica
Por questões de brevidade, você pode optar por importar os métodos das classes a seguir de forma estática para tornar sua query mais sucinta:
AggregatesFiltersProjectionsSortsAccumulators
import static com.mongodb.client.model.Aggregates.*; import static com.mongodb.client.model.Filters.*; import static com.mongodb.client.model.Projections.*; import static com.mongodb.client.model.Sorts.*; import static com.mongodb.client.model.Accumulators.*; import static com.mongodb.client.model.search.SearchPath.fieldPath; import static com.mongodb.client.model.search.VectorSearchOptions.exactVectorSearchOptions; import static com.mongodb.client.model.search.VectorSearchQuery.textQuery; import static java.util.Arrays.asList;
Os exemplos nesta página pressupõem essas importações estáticas, além de importar estaticamente o método asList().
Use esses métodos para criar estágios de pipeline e especificá-los em sua agregação como uma lista:
Bson matchStage = match(eq("some_field", "some_criteria")); Bson sortByCountStage = sortByCount("some_field"); collection.aggregate(asList(matchStage, sortByCountStage)).forEach(doc -> System.out.println(doc));
corresponder
Use o método match() para criar um estágio de pipeline $match que faça a correspondência dos documentos recebidos com o filtro de queries especificado, filtrando os documentos que não correspondem.
Dica
O filtro pode ser uma instância de qualquer classe que implemente o Bson, mas é conveniente combinar com o uso da classe Filtros.
O exemplo a seguir cria um estágio de pipeline que corresponde a todos os documentos em que o campo title é igual a "The Shawshank Redemption":
match(eq("title", "The Shawshank Redemption"));
Projeto
Use o método project() para criar um estágio de pipeline $project em que os campos do documento especificados pelo projeto. A projeção de campos em agregação segue as mesmas regras da projeção de campos em queries.
Dica
Embora a projeção possa ser uma instância de qualquer classe que implemente o Bson, é conveniente combinar com o uso de Projeções.
O exemplo a seguir cria um estágio de pipeline que exclui o campo _id , mas inclui os campos title e plot :
project(fields(include("title", "plot"), excludeId()));
Projetando campos computados
O estágio $project também pode projetar campos calculados.
O exemplo a seguir cria um estágio de pipeline que projeta o campo rated em um novo campo chamado rating, renomeando efetivamente o campo.
project(fields(computed("rating", "$rated"), excludeId()));
Documentos
Use o método documents() para criar um estágio de pipeline $documents que retorna documentos literais a partir de valores de entrada.
Importante
Se você usar um estágio $documents em um pipeline de agregação, ele deverá ser o primeiro estágio no pipeline.
O exemplo abaixo cria um estágio de pipeline que gera documentos de amostra com um campo title:
documents(asList( new Document("title", "The Shawshank Redemption"), new Document("title", "Back to the Future"), new Document("title", "Jurassic Park")));
Importante
Se você usar o método documents() para fornecer a entrada para uma aggregation pipeline, será necessário chamar o método aggregate() em um banco de dados em vez de em uma collection.
Amostra
Use o método sample() para criar um estágio de pipeline $sample para selecionar aleatoriamente documentos da entrada.
O exemplo abaixo cria um estágio de pipeline que seleciona aleatoriamente cinco documentos:
sample(5);
Sort
Use o método sort() para criar um estágio de pipeline $sort para classificar de acordo com os critérios especificados.
Dica
Embora os critérios de classificação possam ser uma instância de qualquer classe que implemente Bson, é melhor usar Sorts junto.
O exemplo a seguir cria um estágio de pipeline que classifica em ordem decrescente de acordo com o valor do campo year e, em seguida, em ordem crescente de acordo com o valor do campo title:
sort(orderBy(descending("year"), ascending("title")));
Ignorar
Use o método skip() para criar um estágio de pipeline $skip para ignorar o número especificado de documentos antes de passar os documentos para o próximo estágio.
O exemplo a seguir cria um estágio de pipeline que ignora os primeiros 5 documentos:
skip(5);
Limite
Use o estágio do pipeline $limit para limitar o número de documentos passados para o próximo estágio.
O exemplo a seguir cria um estágio de pipeline que limita o número de documentos para 10:
limit(10);
Pesquisa
Use o método lookup() para criar um estágio de pipeline $lookup para realizar fusões e subconsultas não correlacionadas entre duas coleções.
Ligação externa esquerda
O exemplo abaixo cria um estágio de pipeline que executa uma junção externa esquerda entre as collections movies e comments:
Une o campo
_iddemoviesao campomovie_idemcommentsEle gera os resultados no campo
joined_comments:
lookup("comments", "_id", "movie_id", "joined_comments");
Participação completa e subqueries não correlacionadas
O exemplo a seguir cria um estágio de pipeline que une duas coleções, orders e warehouses, pelo item e se a quantidade disponível é suficiente para atender à quantidade solicitada:
List<Variable<String>> variables = asList(new Variable<>("order_item", "$item"), new Variable<>("order_qty", "$ordered")); List<Bson> pipeline = asList( match(expr(new Document("$and", asList(new Document("$eq", asList("$$order_item", "$stock_item")), new Document("$gte", asList("$instock", "$$order_qty")))))), project(fields(exclude("stock_item"), excludeId()))); Bson innerJoinLookup = lookup("warehouses", variables, pipeline, "stockdata");
Grupo
Use o método group() para criar um estágio de pipeline $group para agrupar documentos com base em uma determinada expressão e gerar um documento para cada agrupamento distinto.
Dica
O driver inclui a classe Acumuladores com métodos de fábrica estáticos para cada um dos acumuladores suportados.
O exemplo a seguir cria um estágio de pipeline que agrupa documentos pelo valor do campo customerId. Cada grupo acumula a soma e média dos valores do campo quantity nos campos totalQuantity e averageQuantity.
group("$customerId", sum("totalQuantity", "$quantity"), avg("averageQuantity", "$quantity"));
Saiba mais sobre os operadores acumuladores na seção Manual do servidor em Acumuladores.
Pick-N Accumulators
Os acumuladores pick-n são operadores de acumulação de agregação que retornam os elementos superiores e inferiores de acordo com uma ordem específica. Use um dos seguintes construtores para criar um operador de acumulação de agregação:
Dica
Você só pode executar operações de agregação com esses acumuladores de pick-n ao executar o MongoDB v5.2 ou posterior.
Saiba com quais aggregation pipeline stages você pode usar operadores acumuladores acessando a seção manual do servidor sobre Acumuladores.
MinN
The minN() builder creates the $minN accumulator which returns data from documents that contain the n lowest values of a grouping.
Dica
Os acumuladores do $minN e $bottomN podem executar tarefas semelhantes. Consulte Comparação de acumuladores de $minN e $bottomN para uso recomendado de cada um.
O exemplo a seguir demonstra como utilizar o método minN() para retornar os valores mais baixos de três imdb.rating para filmes, agrupados por year:
group( "$year", minN( "lowest_three_ratings", new BsonString("$imdb.rating"), 3 ));
Consulte a documentação da API minN() para obter mais informações.
MaxN
O acumulador maxN() retorna dados de documentos que contêm os n valores mais altos de um agrupamento.
O exemplo a seguir demonstra como usar o método maxN() para retornar os dois maiores valores de imdb.rating para filmes, agrupados por year:
group( "$year", maxN( "highest_two_ratings", new BsonString("$imdb.rating"), 2 ));
Consulte a documentação da API maxN() para obter mais informações.
FirstN
O acumulador firstN() retorna dados dos primeiros n documentos em cada agrupamento para a ordem de classificação especificada.
Dica
Os acumuladores do $firstN e $topN podem executar tarefas semelhantes. Consulte Comparação dos acumuladores $firstN e $topN para saber o uso recomendado de cada um.
O exemplo a seguir demonstra como usar o método firstN() para retornar os quatro primeiros valores de title de filme, com base na ordem em que eles entraram no palco, agrupados por year:
group( "$year", firstN( "first_four_movies", new BsonString("$title"), 4 ));
Consulte a documentação da API firstN() para obter mais informações.
LastN
O acumulador lastN() gera dados dos últimos n documentos em cada agrupamento para a ordem de classificação especificada.
O exemplo a seguir demonstra como usar o método lastN() para mostrar os últimos três valores de title de filme, com base na ordem em que eles entraram no palco, agrupados por year:
group( "$year", lastN( "last_three_movies", new BsonString("$title"), 3 ));
Consulte a documentação da API lastN() para obter mais informações.
principal
O acumulador top() retorna dados do primeiro documento em um grupo com base na ordem de classificação especificada.
O exemplo a seguir demonstra como usar o método top() para retornar os valores title e imdb.rating dos filmes mais bem classificados com base em imdb.rating, agrupados por year.
group( "$year", top( "top_rated_movie", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")) ));
Consulte a documentação da API top() para obter mais informações.
TopN
O acumulador de topN() gera dados de documentos que contêm os valores de n mais altos para o campo especificado.
Dica
Os acumuladores do $firstN e $topN podem executar tarefas semelhantes. Consulte Comparação dos acumuladores $firstN e $topN para saber o uso recomendado de cada um.
O exemplo a seguir demonstra como utilizar o método topN() para retornar os valores title e runtime dos três filmes mais longos com base nos valores runtime, agrupados por year.
group( "$year", topN( "longest_three_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")), 3 ));
Consulte a documentação da API topN() para obter mais informações.
Fundo
O acumulador bottom() retorna dados do último documento em um grupo com base na ordem de classificação especificada.
O exemplo a seguir demonstra como usar o método bottom() para retornar os valores title e runtime do filme mais curto com base no valor runtime, agrupado por year.
group( "$year", bottom( "shortest_movies", descending("runtime"), asList(new BsonString("$title"), new BsonString("$runtime")) ));
Consulte a documentação da API bottom() para obter mais informações.
BottomN
O acumulador de bottomN() retorna dados de documentos que contêm os valores de n mais baixos para o campo especificado.
Dica
Os acumuladores do $minN e $bottomN podem executar tarefas semelhantes. Consulte Comparação de acumuladores de $minN e $bottomN para uso recomendado de cada um.
O exemplo a seguir demonstra como usar o método bottomN() para retornar os valores title e imdb.rating dos dois filmes com classificação mais baixa com base no valor imdb.rating, agrupados por year:
group( "$year", bottomN( "lowest_rated_two_movies", descending("imdb.rating"), asList(new BsonString("$title"), new BsonString("$imdb.rating")), 2 ));
Consulte a documentação da API bottomN() para obter mais informações.
Unwind
Use o método unwind() para criar um estágio de pipeline $unwind para desconstruir um campo de array a partir de documentos de entrada, criando um documento de saída para cada elemento de array.
O exemplo a seguir cria um documento para cada elemento na array sizes:
unwind("$sizes");
Para preservar documentos que têm valores ausentes ou null para o campo de array, ou onde a array está vazia:
unwind("$sizes", new UnwindOptions().preserveNullAndEmptyArrays(true));
Para incluir o índice de array, neste exemplo em um campo denominado "position":
unwind("$sizes", new UnwindOptions().includeArrayIndex("position"));
Fora
Use o método out() para criar um estágio de pipeline $out que grava todos os documentos na coleção especificada no mesmo banco de dados.
Importante
O estágio $out deve ser o último estágio em qualquer pipeline de agregação.
O exemplo a seguir grava os resultados do pipeline na coleção authors :
out("authors");
Merge
Use o método merge() para criar um estágio de pipeline $merge que funde todos os documentos na coleção especificada.
Importante
O estágio $merge deve ser o último estágio em qualquer pipeline de agregação.
O exemplo a seguir mescla o pipeline na coleção authors utilizando as opções padrão:
merge("authors");
O exemplo abaixo mescla o pipeline na collection customers no banco de dados reporting usando algumas opções que especificam a substituição do documento se date e customerId corresponderem. Caso contrário, insira o documento:
merge(new MongoNamespace("reporting", "customers"), new MergeOptions().uniqueIdentifier(asList("date", "customerId")) .whenMatched(MergeOptions.WhenMatched.REPLACE) .whenNotMatched(MergeOptions.WhenNotMatched.INSERT));
GraphLookup
Use o método graphLookup() para criar um estágio de pipeline $graphLookup que executa uma pesquisa recursiva em uma collection especificada para corresponder a um campo especificado em um documento a um campo especificado de outro documento.
O exemplo abaixo calcula o gráfico da rede social para usuários na collection contacts, fazendo a correspondência recursiva do valor no campo friends com o campo name:
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork");
Utilizando o GraphLookupOptions, você pode especificar a profundidade para recursar como também o nome do campo de profundidade, se desejado. Neste exemplo, $graphLookup recursará até duas vezes e criará um campo chamado degrees com as informações de profundidade de recursão para cada documento.
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(2).depthField("degrees"));
Usando GraphLookupOptions, você pode especificar um filtro ao qual os documentos devem corresponder para que o MongoDB os inclua em sua pesquisa. Neste exemplo, apenas links com "golfe" no campo hobbies serão incluídos.
graphLookup("contacts", "$friends", "friends", "name", "socialNetwork", new GraphLookupOptions().maxDepth(1).restrictSearchWithMatch(eq("hobbies", "golf")));
SortByCount
Use o método sortByCount() para criar um estágio de pipeline $sortByCount que agrupa documentos por uma determinada expressão e, em seguida, classifica esses grupos por contagem em ordem decrescente.
Dica
O estágio $sortByCount é idêntico a um estágio $group com um acumulador de $sum seguido por um estágio $sort.
[ { "$group": { "_id": <expression to group on>, "count": { "$sum": 1 } } }, { "$sort": { "count": -1 } } ]
O exemplo a seguir agrupa documentos pelo valor truncado do campo x e calcula a contagem para cada valor distinto:
sortByCount(new Document("$floor", "$x"));
ReplaceRoot
Use o método replaceRoot() para criar um estágio de pipeline $replaceRoot que substitui cada documento de entrada pelo documento especificado.
O exemplo abaixo substitui cada documento de entrada pelo documento aninhado no campo spanish_translation:
replaceRoot("$spanish_translation");
AddFields
Use o método addFields() para criar um estágio de pipeline $addFields que adiciona novos campos a documentos.
Dica
Utilize o $addFields se você não quer a inclusão ou exclusão do campo do projeto.
O exemplo seguinte adiciona dois novos campos, a e b para os documentos de entrada:
addFields(new Field("a", 1), new Field("b", 2));
Contar
Use the count() method to create a $count pipeline stage that counts the number of documents that enter the stage, and assigns that value to a specified field name. If you do not specify a field, count() defaults the field name to "count".
Dica
O estágio $count é o açúcar sintático para:
{ "$group":{ "_id": 0, "count": { "$sum" : 1 } } }
O exemplo a seguir cria um estágio de pipeline que gera a contagem de documentos recebidos em um campo chamado "total":
count("total");
Balde
Use o método bucket() para criar um estágio de pipeline $bucket que automatize o agrupamento de dados em torno de valores de limite predefinidos.
O exemplo abaixo cria um estágio de pipeline que agrupa os documentos recebidos com base no valor do campo screenSize, incluindo o limite inferior e excluindo o limite superior.
bucket("$screenSize", asList(0, 24, 32, 50, 70, 200));
Utilize a classe BucketOptions para especificar um contêiner padrão para valores fora dos limites especificados e para especificar acumuladores adicionais.
O exemplo abaixo cria um estágio de pipeline que agrupa documentos de entrada com base no valor de seu campo screenSize, contando o número de documentos que entram em cada bucket, empurrando o valor de screenSize para um campo chamado matches, e capturando qualquer tamanho de tela maior que "70" em um bucket chamado "monster" para tamanhos de tela monstruosamente grandes:
Dica
O driver inclui a classe Acumuladores com métodos de fábrica estáticos para cada um dos acumuladores suportados.
bucket("$screenSize", asList(0, 24, 32, 50, 70), new BucketOptions().defaultBucket("monster").output(sum("count", 1), push("matches", "$screenSize")));
BucketAuto
Use o método bucketAuto() para criar um estágio de pipeline $bucketAuto que determina automaticamente os limites de cada bucket em sua tentativa de distribuir os documentos uniformemente em um número especificado de buckets.
O exemplo a seguir cria um estágio de pipeline que tentará criar e distribuir uniformemente documentos em 10 buckets usando o valor de seu campo price :
bucketAuto("$price", 10);
Utilize a classe BucketAutoOptions para especificar um esquema baseado em número preferido para definir valores de limite e especificar acumuladores adicionais.
O exemplo a seguir cria um estágio de pipeline que tentará criar e distribuir uniformemente documentos em 10 buckets usando o valor de seu campo price, definindo os limites de bucket em potências de 2 (2, 4, 8, 16, ...). Ele também conta o número de documentos em cada bucket e calcula sua price média em um novo campo chamado avgPrice:
Dica
O driver inclui a classe Acumuladores com métodos de fábrica estáticos para cada um dos acumuladores suportados.
bucketAuto("$price", 10, new BucketAutoOptions().granularity(BucketGranularity.POWERSOF2) .output(sum("count", 1), avg("avgPrice", "$price")));
Facet
Use o método facet() para criar um estágio de pipeline $facet que permitirá a definição de pipelines paralelos.
O exemplo a seguir cria um estágio de pipeline que executa duas agregações paralelas:
A primeira agregação distribui documentos recebidos em 5 grupos de acordo com seu campo
attributes.screen_size.A segunda aggregation conta todos os fabricantes e gera sua contagem, limitada aos cinco principais.
facet(new Facet("Screen Sizes", bucketAuto("$attributes.screen_size", 5, new BucketAutoOptions().output(sum("count", 1)))), new Facet("Manufacturer", sortByCount("$attributes.manufacturer"), limit(5)));
DefinirWindowFields
Use o método setWindowFields() para criar um estágio de pipeline $setWindowFields que permite usar operadores de janela para realizar operações em uma extensão específica de documentos em uma coleção.
Dica
Funções de janela
O driver inclui a classe Windows com métodos de fábrica estáticos para criar cálculos em janela.
O exemplo a seguir cria um estágio de tubulação que calcula a precipitação acumulada e a temperatura média no mês passado para cada localidade a partir de medições mais refinadas apresentadas nos campos rainfall e temperature:
Window pastMonth = Windows.timeRange(-1, MongoTimeUnit.MONTH, Windows.Bound.CURRENT); setWindowFields("$localityId", Sorts.ascending("measurementDateTime"), WindowOutputFields.sum("monthlyRainfall", "$rainfall", pastMonth), WindowOutputFields.avg("monthlyAvgTemp", "$temperature", pastMonth));
Densificar
Utilize o método densify() para criar um estágio de pipeline $densify que gera uma sequência de documentos para abranger um intervalo especificado.
Dica
Você pode usar o estágio de agregação do $densify() somente ao executar MongoDB v5.1 ou posterior.
Consider the following documents retrieved from the Atlas sample weather dataset that contain measurements for a similar position field, spaced one hour apart:
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
Suponha que você precise criar um estágio de pipeline que execute as seguintes ações nesses documentos:
Adicione um documento a cada intervalo de
tsminutos para o qual um valor de ainda não existe.Agrupe os documentos pelo campo
position.
A chamada para o construtor de estágio de agregação do densify() que realiza estas ações se assemelha ao seguinte:
densify( "ts", DensifyRange.partitionRangeWithStep(15, MongoTimeUnit.MINUTE), DensifyOptions.densifyOptions().partitionByFields("position.coordinates"));
A saída a seguir destaca os documentos gerados pelo estágio agregado que contêm valores ts a cada 15 minutos entre os documentos existentes:
Document{{ _id=5553a..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:00:00 EST 1984, ... }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:15:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:30:00 EST 1984 }} Document{{ position=Document{{coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 08:45:00 EST 1984 }} Document{{ _id=5553b..., position=Document{{type=Point, coordinates=[-47.9, 47.6]}}, ts=Mon Mar 05 09:00:00 EST 1984, ... }}
Consulte a documentação da API do pacote densify para obter mais informações.
Fill
Use the fill() method to create a $fill pipeline stage that populates null and missing field values.
Dica
Você pode usar o estágio de agregação do $fill() somente ao executar MongoDB v5,3 ou posterior.
Considere os seguintes documentos que contêm medições de temperatura e pressão de ar em um intervalo de hora em hora:
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C}} Document{{_id=6308c..., hour=3, temperature=null, air_pressure=29.76}}
Suponha que você precisasse preencher os pontos de dados ausentes de temperatura e pressão atmosférica nos documentos da seguinte forma:
Preencha o campo
air_pressurepara hora "2" utilizando interpolação linear para calcular o valor.Defina o valor
temperatureausente para " 23.6C " por hora "3".
A chamada para o construtor de estágio de agregação do fill() que realiza estas ações se assemelha ao seguinte:
fill( FillOptions.fillOptions().sortBy(ascending("hour")), FillOutputField.value("temperature", "23.6C"), FillOutputField.linear("air_pressure") );
A saída a seguir destaca os documentos que contêm campos preenchidos pelo estágio agregado:
Document{{_id=6308a..., hour=1, temperature=23C, air_pressure=29.74}} Document{{_id=6308b..., hour=2, temperature=23.5C, air_pressure=29.75}} Document{{_id=6308c..., hour=3, temperature=23.6C, air_pressure=29.76}}
Consulte a documentação completa da API do pacote para obter mais informações.
MongoDB Search
Utilize o método search() para criar um estágio de pipeline $search que especifica uma Full Text Search de um ou mais campos.
Observação
Requisitos da versão do Atlas e Community Edition
O $search operador de pipeline de agregação está disponível somente para coleções hospedadas em clusters do MongoDB Atlas que executam o MongoDB 4 v.2 ou posterior, ou em clusters do MongoDB Community Edition que executam o MongoDB8 v.2 ou posterior. As collections devem ser cobertas por um índice do MongoDB Search. Para saber mais sobre a configuração necessária e a funcionalidade desse operador, consulte a documentação do MongoDB Search.
O exemplo abaixo cria um estágio de pipeline que pesquisa no campo title o texto que contém a palavra "Future":
Bson textSearch = Aggregates.search( SearchOperator.text( fieldPath("title"), "Future"));
Saiba mais sobre os construtores na documentação da API do pacote de pesquisa.
Metadados de pesquisa do MongoDB
Use o método searchMeta() para criar um estágio de pipeline $searchMeta que retorna somente a parte de metadados dos resultados das query de pesquisa do MongoDB Search.
Observação
Requisitos da versão do Atlas e Community Edition
Este operador de pipeline de agregação está disponível somente em clusters do MongoDB Atlas executando 4 4v..11 e posterior, ou em clusters do MongoDB Community Edition executando MongoDB8 v.2 ou posterior. Para uma lista detalhada de disponibilidade de versão, consulte a documentação do MongoDB Atlas em $searchMeta.
O exemplo a seguir mostra os metadados count para um estágio de agregação do MongoDB pesquisa:
Aggregates.searchMeta( SearchOperator.near(2010, 1, fieldPath("year")));
Saiba mais sobre esse assistente na documentação da API searchMeta().