MongoDB - agregação
As operações de agregação processam registros de dados e retornam resultados computados. As operações de agregação agrupam valores de vários documentos e podem executar uma variedade de operações nos dados agrupados para retornar um único resultado. Na contagem SQL (*) e com group by é um equivalente à agregação MongoDB.
O método aggregate ()
Para a agregação no MongoDB, você deve usar aggregate() método.
Sintaxe
Sintaxe básica de aggregate() método é o seguinte -
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
Exemplo
Na coleção, você tem os seguintes dados -
{
_id: ObjectId(7df78ad8902c)
title: 'MongoDB Overview',
description: 'MongoDB is no sql database',
by_user: 'tutorials point',
url: 'http://www.tutorialspoint.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: 'NoSQL Overview',
description: 'No sql database is very fast',
by_user: 'tutorials point',
url: 'http://www.tutorialspoint.com',
tags: ['mongodb', 'database', 'NoSQL'],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: 'Neo4j Overview',
description: 'Neo4j is no sql database',
by_user: 'Neo4j',
url: 'http://www.neo4j.com',
tags: ['neo4j', 'database', 'NoSQL'],
likes: 750
},
Agora, da coleção acima, se você deseja exibir uma lista informando quantos tutoriais são escritos por cada usuário, você usará o seguinte aggregate() método -
> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{ "_id" : "tutorials point", "num_tutorial" : 2 }
{ "_id" : "Neo4j", "num_tutorial" : 1 }
>
A consulta SQL equivalente para o caso de uso acima será select by_user, count(*) from mycol group by by_user.
No exemplo acima, agrupamos os documentos por campo by_usere em cada ocorrência pelo usuário, o valor anterior da soma é incrementado. A seguir está uma lista de expressões de agregação disponíveis.
Expressão | Descrição | Exemplo |
---|---|---|
$ soma | Soma o valor definido de todos os documentos da coleção. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", num_tutorial: {$ sum: "$ likes"}}}]) |
$ médio | Calcula a média de todos os valores fornecidos de todos os documentos da coleção. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", num_tutorial: {$ avg: "$ likes"}}}]) |
$ min | Obtém o mínimo dos valores correspondentes de todos os documentos da coleção. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", num_tutorial: {$ min: "$ likes"}}}]) |
$ max | Obtém o máximo dos valores correspondentes de todos os documentos da coleção. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", num_tutorial: {$ max: "$ likes"}}}]) |
$ push | Insere o valor em uma matriz no documento resultante. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", url: {$ push: "$ url"}}}]) |
$ addToSet | Insere o valor em uma matriz no documento resultante, mas não cria duplicatas. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", url: {$ addToSet: "$ url"}}}]) |
$ primeiro | Obtém o primeiro documento dos documentos de origem de acordo com o agrupamento. Normalmente, isso só faz sentido junto com algum estágio “$ sort” aplicado anteriormente. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", first_url: {$ first: "$ url"}}}]) |
$ último | Obtém o último documento dos documentos de origem de acordo com o agrupamento. Normalmente, isso só faz sentido junto com algum estágio “$ sort” aplicado anteriormente. | db.mycol.aggregate ([{$ group: {_id: "$ by_user", last_url: {$ last: "$ url"}}}]) |
Conceito de Pipeline
No comando UNIX, shell pipeline significa a possibilidade de executar uma operação em alguma entrada e usar a saída como entrada para o próximo comando e assim por diante. O MongoDB também suporta o mesmo conceito na estrutura de agregação. Há um conjunto de estágios possíveis e cada um deles é considerado um conjunto de documentos como uma entrada e produz um conjunto resultante de documentos (ou o documento JSON final resultante no final do pipeline). Isso pode então ser usado para o próximo estágio e assim por diante.
A seguir estão os estágios possíveis na estrutura de agregação -
$project - Usado para selecionar alguns campos específicos de uma coleção.
$match - Esta é uma operação de filtragem e, portanto, pode reduzir a quantidade de documentos que são dados como entrada para a próxima etapa.
$group - Isso faz a agregação real conforme discutido acima.
$sort - Classifica os documentos.
$skip - Com isso, é possível avançar na lista de documentos para uma determinada quantidade de documentos.
$limit - Isso limita a quantidade de documentos a serem examinados, pelo número fornecido a partir das posições atuais.
$unwind- Isso é usado para desenrolar documentos que estão usando matrizes. Ao usar uma matriz, os dados são uma espécie de pré-agregados e esta operação será desfeita com isso para ter documentos individuais novamente. Assim, com esta etapa iremos aumentar a quantidade de documentos para a próxima etapa.