Menu Docs
Página inicial do Docs
/ / /
Java síncrono
/ /

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

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));

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"));

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()));

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()));

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);

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")));

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);

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);

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.

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 de movies ao campo movie_id em comments

  • Ele gera os resultados no campo joined_comments:

lookup("comments", "_id", "movie_id", "joined_comments");

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");

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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"));

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");

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));

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")));

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"));

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");

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));

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");

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")));

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")));

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)));

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));

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.

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.

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.

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().

Voltar

Construtores