Construtores de agregados
Nesta página
- Visão geral
- corresponder
- Projeto
- Projetando campos computados
- Amostra
- Sort
- Ignorar
- Limite
- Pesquisa
- Ligação externa esquerda
- Participação completa e subqueries não correlacionadas
- Grupo
- Pick-N Accumulators
- MinN
- MaxN
- FirstN
- LastN
- principal
- TopN
- Fundo
- BottomN
- Unwind
- Fora
- Merge
- GraphLookup
- SortByCount
- ReplaceRoot
- AddFields
- Contar
- Balde
- BucketAuto
- Facet
- DefinirWindowFields
- Densificar
- Fill
- Pesquisa de texto completo do Atlas
- Metadados de Atlas Search
Visão geral
Neste guia, veja como usar a classe Agregados que fornece métodos estáticos de fábrica para construir pipeline de agregação stages no driver Java do MongoDB.
Para uma introdução mais completa à Agregação, consulte nossoGuia de Agregaçãodo .
Dica
Por questões de brevidade, você pode optar por importar os métodos das classes a seguir de forma estática para tornar suas queries mais sucintas:
Aggregates
Filters
Projections
Sorts
Accumulators
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 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()));
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
_id
demovies
ao campomovie_id
emcomments
Ele 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()))); List<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 pipeline de agregação stages você pode usar operadores acumuladores acessando a seção manual do servidor sobre Acumuladores.
MinN
O construtor minN()
cria o acumulador $minN que retorna dados de documentos que contêm os n
menores valores de um agrupamento.
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 coleção 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 o método count()
para criar um estágio de pipeline $count que conta o número de documentos que entram no estágio e atribui esse valor a um nome de campo especificado. Se você não especificar um campo, count()
padronizará o nome do campo para "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 blocos 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.
Considere os seguintes documentos recuperados do conjunto de dados meteorológicos de amostra do Atlas que contêm medições para um campo position
semelhante, espaçados em uma hora:
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
ts
minutos 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 essas ações deve se assemelhar 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 o método fill()
para criar um estágio de pipeline $fill que preencha null
e os valores de campo ausentes.
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_pressure
para hora "2" utilizando interpolação linear para calcular o valor.Defina o valor
temperature
ausente 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.
Pesquisa de texto completo do Atlas
Utilize o método search()
para criar um estágio de pipeline $search que especifica uma Full Text Search de um ou mais campos.
Dica
Disponível apenas no Atlas para MongoDB v4.2 e posterior
Esse operador de pipeline de agregação só está disponível para coleções hospedadas em clusters do MongoDB Atlas executando v4.2 ou posterior que são cobertas por um índice de Atlas Search. Saiba mais sobre a configuração necessária e a funcionalidade desse operador na documentação do Atlas 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( SearchPath.fieldPath("title"), "Future"));
Saiba mais sobre os construtores na documentação da API do pacote de pesquisa.
Metadados de Atlas Search
Use o método searchMeta()
para criar um estágio de pipeline $searchMeta que retorna somente a parte de metadados dos resultados das queries de Full Text Search do Atlas.
Dica
Disponível apenas no Atlas para MongoDB v4,4,11 e posterior
Este operador de pipeline de agregação só está disponível em clusters do MongoDB Atlas que executam v4.4.11 e 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 de pesquisa do Atlas:
Aggregates.searchMeta( SearchOperator.near(2010, 1, SearchPath.fieldPath("year")));
Saiba mais sobre esse assistente na documentação da API searchMeta().