db.collection.aggregate()
MongoDB com drivers
Esta página documenta um método mongosh
. Para ver o método equivalente em um driver MongoDB, consulte a página correspondente da sua linguagem de programação:
Definição
db.collection.aggregate(pipeline, options)
Calcula valores agregados para os dados em uma coleção ou uma visualização.
Retorna: - Um cursor para os documentos produzidos pela etapa final do pipeline de agregação.
- Se o pipeline incluir a opção
explain
, a query retornará um documento que fornecerá detalhes sobre o processamento da operação de agregação. - Se o pipeline incluir os operadores
$out
ou$merge
, a query retornará um cursor vazio.
Compatibilidade
Você pode utilizar o db.collection.aggregate()
para implantações hospedadas nos seguintes ambientes:
MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem
MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB
MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB
Sintaxe
O método aggregate()
tem o seguinte formato:
db.collection.aggregate( <pipeline>, <options> )
O método aggregate()
utiliza os seguintes parâmetros:
Parâmetro | Tipo | Descrição |
---|---|---|
pipeline | array | Uma sequência de etapas ou operações de agregação de dados. Consulte os operadores de pipeline de agregação para obter detalhes. O método ainda pode aceitar os estágios do pipeline como argumentos separados em vez de elementos em uma array; no entanto, se você não especificar o |
options | documento | Opcional. Opções adicionais que o aggregate() passa para o comando aggregate . Disponível somente se você especificar pipeline como uma array. Para ver as opções disponíveis, consulte AggregateOptions. |
Comportamento
Error Handling
Se ocorrer um erro, o auxiliar aggregate()
lançará uma exceção.
Comportamento do cursor
Em mongosh
, se o cursor retornado do db.collection.aggregate()
não for atribuído a uma variável utilizando a palavra-chave var
, então mongosh
automaticamente iterará o cursor até 20 vezes. Consulte Iterar um cursor em mongosh
para manipular cursores em mongosh
.
Os cursores retornados da agregação suportam apenas métodos de cursor que operam em cursores avaliados (ou seja, cursores cujo primeiro lote foi recuperado), como os seguintes métodos:
Para mais informações, veja:
Sessões
Para cursores criados dentro de uma sessão, você não pode chamar getMore
fora da sessão.
Da mesma forma, para cursores criados fora de uma sessão, você não pode chamar getMore
dentro de uma sessão.
Tempo-limite de inatividade da sessão
Os drivers MongoDB e mongosh
associam todas as operações a uma sessão do servidor, com exceção das operações de gravação não reconhecidas. No caso das operações não associadas explicitamente a uma sessão (ou seja, usando Mongo.startSession()
), os drivers MongoDB e mongosh
criam uma sessão implícita e a associam à operação.
Se uma sessão estiver ociosa por mais de 30 minutos, o servidor MongoDB marcará essa sessão como expirada e poderá fechá-la a qualquer momento. Quando o servidor MongoDB fecha a sessão, ele também elimina todas as operações em andamento e abre os cursores associados à sessão. Isso inclui cursores configurados com noCursorTimeout()
ou maxTimeMS()
com mais de 30 minutos.
Para operações que retornam um cursor, se o cursor puder ficar ocioso por mais de 30 minutos, emita a operação em uma sessão explícita usando Mongo.startSession()
e atualize periodicamente a sessão usando o comando refreshSessions
. Consulte Tempo limite de inatividade da sessão para obter mais informações.
Transações
db.collection.aggregate()
pode ser usado dentro de transações distribuídas.
No entanto, os seguintes estágios não são permitidos nas transações:
Você também não pode especificar a opção explain
.
Para cursores criados fora de uma transação, você não pode chamar
getMore
dentro da transação.Para cursores criados em uma transação, não é possível chamar
getMore
fora da transação.
Importante
Na maioria dos casos, uma transação distribuída incorre em um custo de desempenho maior do que as gravações de um único documento, e a disponibilidade de transações distribuídas não deve substituir o design eficaz do esquema. Em muitos cenários, o modelo de dados desnormalizado (documentos e arrays incorporados) continuará a ser ideal para seus dados e casos de uso. Ou seja, para muitos cenários, modelar seus dados adequadamente minimizará a necessidade de transações distribuídas.
Para considerações adicionais sobre o uso de transações (como limite de tempo de execução e limite de tamanho do oplog), consulte também Considerações de produção.
Desconexão do cliente
Para db.collection.aggregate()
a operação que não inclua os estágios $out
ou $merge
:
A partir do MongoDB 4.2, se o cliente que emitiu db.collection.aggregate()
se desconectar antes da conclusão da operação, o MongoDB marcará db.collection.aggregate()
para encerramento usando killOp
.
Configurações de query
Novidades na versão 8.0.
Você pode usar as configurações de query para definir dicas de índice, definir filtros de descarte de operação e outros campos. As configurações se aplicam à forma de query em todo o cluster. O cluster mantém as configurações após o fechamento.
O otimizador de query usa as configurações da query como uma entrada adicional durante o planejamento da query, o que afeta o plano selecionado para executar a query. Você também pode usar as configurações de query para bloquear uma forma de query.
Para adicionar configurações de query e explorar exemplos, consulte setQuerySettings
.
Você pode adicionar configurações de consulta para os comandos find
, distinct
e aggregate
.
As configurações de consulta têm mais funcionalidade e são preferidas em relação aos filtros de índice obsoletos.
Para remover as configurações de query, use removeQuerySettings
. Para obter as configurações de consulta, use um estágio $querySettings
em um pipeline de agregação .
Exemplos
Os exemplos seguintes utilizam a coleção orders
que contém os seguintes documentos:
db.orders.insertMany( [ { _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }, { _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }, { _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }, { _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }, { _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 } ] )
Agrupar por e calcular uma soma
A operação de agregação seguinte seleciona documentos com status igual a "A"
, agrupa os documentos correspondentes pelo campo cust_id
e calcula o total
para cada campo cust_id
a partir da soma do campo amount
e classifica os resultados pelo campo total
em ordem decrescente:
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
A operação retorna um cursor com os seguintes documentos:
[ { _id: "xyz1", total: 100 }, { _id: "abc1", total: 75 } ]
mongosh
itera o cursor retornado automaticamente para imprimir os resultados. Consulte Iterar um cursor em mongosh
para manipular cursores manualmente no mongosh
.
Retornar informações sobre a operação do pipeline de agregação
O exemplo a seguir usa db.collection.explain()
para visualizar informações detalhadas sobre o plano de execução do pipeline de agregação.
db.orders.explain().aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } } ] )
A operação retorna um documento que detalha o processamento do pipeline de agregação . Por exemplo, o documento pode mostrar, entre outros detalhes, qual índice, se houver, a operação utilizada. [1] Se a orders
for uma coleção fragmentada, o documento também mostrará a divisão de trabalho entre os fragmentos e a operação de mesclagem e, para queries direcionadas, os fragmentos direcionados.
Observação
Os leitores pretendidos do documento de saída explain
são humanos, e não máquinas, e o formato de saída está sujeito a alterações entre as versões.
Você pode ver uma saída de explicação mais detalhada passando os modos de explicação executionStats
ou allPlansExecution
para o método db.collection.explain()
.
[1] | Filtros de Índice podem afetar a escolha do índice usado. Consulte Filtros de Índice para obter detalhes. |
Interação com allowDiskUseByDefault
A partir do MongoDB 6.0, os estágios do pipeline que exigem mais de 100 megabytes de memória para execução gravam arquivos temporários no disco por padrão. Esses arquivos temporários duram durante a execução do pipeline e podem influenciar o espaço de armazenamento na sua instância. Em versões anteriores do MongoDB, você deve passar { allowDiskUse: true }
para find
individuais e comandos aggregate
para habilitar esse comportamento.
Somente find
e aggregate
comandos podem substituir o parâmetro allowDiskUseByDefault
por um ou outro:
Usando
{ allowDiskUse: true }
para permitir a gravação de arquivos temporários no disco quandoallowDiskUseByDefault
estiver definido comofalse
Usando
{ allowDiskUse: false }
para proibir a gravação de arquivos temporários no disco quandoallowDiskUseByDefault
estiver definido comotrue
As mensagens de registro do criador de perfil e as mensagens de registro de diagnóstico incluem um indicador usedDisk
se algum estágio de agregação gravou dados em arquivos temporários devido a restrições de memória.
Para obter mais informações, consulte Limites do pipeline de agregação.
Especifique um tamanho de lote inicial
Para especificar um tamanho de lote inicial para o cursor, utilize a seguinte sintaxe para a opção cursor
:
cursor: { batchSize: <int> }
Por exemplo, a seguinte operação de agregação especifica o tamanho de lote inicial de 0
para o cursor:
db.orders.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, { $sort: { total: -1 } }, { $limit: 2 } ], { cursor: { batchSize: 0 } } )
O documento do { cursor: { batchSize: 0 } }
, que especifica o tamanho do tamanho do lote inicial, indica um primeiro lote vazio. Esse tamanho de lote é útil para retornar rapidamente um cursor ou uma mensagem de falha sem realizar um trabalho significativo no lado do servidor.
Para especificar o tamanho do lote para operações subsequentes do getMore
(após o lote inicial), utilize o campo batchSize
ao executar o comando getMore
.
mongosh
itera o cursor retornado automaticamente para imprimir os resultados. Consulte Iterar um cursor em mongosh
para manipular cursores manualmente no mongosh
.
Especificar um agrupamento
A colocação permite que os usuários especifiquem regras específicas do idioma para comparação de strings, como regras para letras maiúsculas e marcas de acento.
Uma coleção restaurants
possui os seguintes documentos:
db.restaurants.insertMany( [ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ] )
A operação de agregação a seguir inclui a opção de agrupamento :
db.restaurants.aggregate( [ { $match: { status: "A" } }, { $group: { _id: "$category", count: { $sum: 1 } } } ], { collation: { locale: "fr", strength: 1 } } );
Observação
Se executar uma aggregation que envolve múltiplas visualizações, como com $lookup
ou $graphLookup
, as visualizações deverão ter o mesmo agrupamento.
Para obter descrições sobre os campos de agrupamento, consulte Documento de agrupamento.
Sugerir um Índice
Crie uma collection food
com os seguintes documentos:
db.food.insertMany( [ { _id: 1, category: "cake", type: "chocolate", qty: 10 }, { _id: 2, category: "cake", type: "ice cream", qty: 25 }, { _id: 3, category: "pie", type: "boston cream", qty: 20 }, { _id: 4, category: "pie", type: "blueberry", qty: 15 } ] )
Crie os seguintes índices:
db.food.createIndex( { qty: 1, type: 1 } ); db.food.createIndex( { qty: 1, category: 1 } );
A seguinte operação de aggregation inclui a opção hint
para forçar o uso do índice especificado:
db.food.aggregate( [ { $sort: { qty: 1 }}, { $match: { category: "cake", qty: 10 } }, { $sort: { type: -1 } } ], { hint: { qty: 1, category: 1 } } )
Sobrepor readConcern
Utilize a opção readConcern
para especificar o read concern para a operação.
Não é possível usar o estágio $out
ou $merge
em conjunto com a preocupação de leitura "linearizable"
. Ou seja, se você especificar a preocupação de leitura "linearizable"
para db.collection.aggregate()
, não poderá incluir nenhum dos estágios no pipeline.
A operação a seguir em um conjunto de réplicas especifica uma read concern de "majority"
para ler a cópia mais recente dos dados confirmados como gravados na maioria dos nós.
Observação
Para garantir que um único thread possa ler suas próprias gravações, use
"majority"
read concern e"majority"
write concern em relação ao primário do conjunto de réplicas.Você pode especificar o nível de preocupação de leitura
"majority"
para uma agregação que inclui um estágio$out
.Independentemente do nível de read concern, os dados mais recentes em um nó podem não refletir a versão mais recente dos dados no sistema.
db.restaurants.aggregate( [ { $match: { rating: { $lt: 5 } } } ], { readConcern: { level: "majority" } } )
Especifique um comentário
Uma coleção denominada movies
contém documentos formatados como tal:
db.movies.insertOne( { _id: ObjectId("599b3b54b8ffff5d1cd323d8"), title: "Jaws", year: 1975, imdb: "tt0073195" } )
A operação de agregação a seguir encontra filmes criados em 1995 e inclui a comment
opção para fornecer informações de rastreamento logs
na db.system.profile
coleção , coleção e db.currentOp
.
db.movies.aggregate( [ { $match: { year : 1995 } } ], { comment : "match_all_movies_from_1995" } ).pretty()
Em um sistema com a criação de perfil ativada, você pode system.profile
a para ver todas as agregações semelhantes recentes, conforme mostrado abaixo:
db.system.profile.find( { "command.aggregate": "movies", "command.comment" : "match_all_movies_from_1995" } ).sort( { ts : -1 } ).pretty()
Isso retornará um conjunto de resultados do perfil no seguinte formato:
{ "op" : "command", "ns" : "video.movies", "command" : { "aggregate" : "movies", "pipeline" : [ { "$match" : { "year" : 1995 } } ], "comment" : "match_all_movies_from_1995", "cursor" : { }, "$db" : "video" }, ... }
Um aplicativo pode codificar qualquer informação arbitrária no comentário para rastrear ou identificar com mais facilidade operações específicas por meio do sistema. Por exemplo, um aplicativo pode anexar um comentário de string incorporando seu ID de processo, ID de thread, nome de host do cliente e o usuário que emitiu o comando.
Usar variáveis em let
Novidades na versão 5.0.
Para definir variáveis que você pode acessar em outro lugar no comando, utilize a opção let
.
Observação
Crie uma collection cakeSales
contendo vendas para sabores de bolo:
db.cakeSales.insertMany( [ { _id: 1, flavor: "chocolate", salesTotal: 1580 }, { _id: 2, flavor: "strawberry", salesTotal: 4350 }, { _id: 3, flavor: "cherry", salesTotal: 2150 } ] )
O seguinte exemplo:
recupera o bolo que tem um
salesTotal
maior que 3000, que é o bolo com um_id
de 2define uma variável
targetTotal
emlet
, que é referenciada em$gt
como$$targetTotal
db.cakeSales.aggregate( [ { $match: { $expr: { $gt: [ "$salesTotal", "$$targetTotal" ] } } } ], { let: { targetTotal: 3000 } } )