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.