MongoDB Aggregation

MongoDB Aggregation

Descubra como processar documentos distintos agrupados em uma única saída para facilitar a geração de resultados e performance quando preciso efetuar buscas em banco de dados MongoDB

A seguir explicarei vários parâmetros de como utilizar esse recurso e elaborar buscas mais específicas no MongoDB.

Atenção: Todos os comandos abaixo foram executados na versão 3.4 do MongoDB.

alisson@alisson-pc:~/MoodlePlus$ mongo
MongoDB shell version: 3.2.11
connecting to: test
use exemplo
switched to db exemplo

No log acima entrei no console do MongoDB e acessei o  banco exemplo, nesse banco vou criar uma collection chamada funcionários e inserir alguns registros:

db.funcionarios.insert({"nome":"Alisson","sobrenome":"Machado de Menezes","cargo":"Analista de Sistemas DevOps", "empresa":"4Linux"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Mariana","sobrenome":"Albano","cargo":"Analista de Sistemas DevOps", "empresa":"4Linux"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Antonio","sobrenome":"Gomes","cargo":"Supervidor de Suporte", "empresa":"4Linux"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Gabriel","sobrenome":"Bonfim","cargo":"Desenvolvedor Senior", "empresa":"4Linux"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Hederson","sobrenome":"Boechat","cargo":"Desenvolvedor Senior", "empresa":"Nadir"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Guilherme","sobrenome":"Chagas","cargo":"Analista de Sistemas DevOps", "empresa":"BankFacil"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Hederson","sobrenome":"Boechat","cargo":"Desenvolvedor Senior", "empresa":"Nadir"})
WriteResult({ "nInserted" : 1 })

db.funcionarios.insert({"nome":"Fernando","sobrenome":"Paiva","cargo":"Analista de B.I", "empresa":"Lemman"})
WriteResult({ "nInserted" : 1 })


Para listar todos os documentos digite a instrução abaixo:

db.funcionarios.find()

{ "_id" : ObjectId("58a7479844f122d1903c551f"), "nome" : "Alisson", "sobrenome" : "Machado de Menezes", "cargo" : "Analista de Sistemas DevOps", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747a144f122d1903c5520"), "nome" : "Mariana", "sobrenome" : "Albano", "cargo" : "Analista de Sistemas DevOps", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747ac44f122d1903c5521"), "nome" : "Antonio", "sobrenome" : "Gomes", "cargo" : "Supervidor de Suporte", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747b644f122d1903c5522"), "nome" : "Gabriel", "sobrenome" : "Bonfim", "cargo" : "Desenvolvedor Senior", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747c044f122d1903c5523"), "nome" : "Hederson", "sobrenome" : "Boechat", "cargo" : "Desenvolvedor Senior", "empresa" : "Nadir" }
{ "_id" : ObjectId("58a747c844f122d1903c5524"), "nome" : "Guilherme", "sobrenome" : "Chagas", "cargo" : "Analista de Sistemas DevOps", "empresa" : "BankFacil" }
{ "_id" : ObjectId("58a747d144f122d1903c5525"), "nome" : "Hederson", "sobrenome" : "Boechat", "cargo" : "Desenvolvedor Senior", "empresa" : "Nadir" }
{ "_id" : ObjectId("58a747da44f122d1903c5526"), "nome" : "Fernando", "sobrenome" : "Paiva", "cargo" : "Analista de B.I", "empresa" : "Lemman" }

Agora que a base dados já está populada é possível utilizar do aggregate para filtrar essas buscas.

Por exemplo, se eu quiser buscar todos os funcionários que trabalhando na empresa 4linux:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}}])
{ "_id" : ObjectId("58a7479844f122d1903c551f"), "nome" : "Alisson", "sobrenome" : "Machado de Menezes", "cargo" : "Analista de Sistemas DevOps", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747a144f122d1903c5520"), "nome" : "Mariana", "sobrenome" : "Albano", "cargo" : "Analista de Sistemas DevOps", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747ac44f122d1903c5521"), "nome" : "Antonio", "sobrenome" : "Gomes", "cargo" : "Supervidor de Suporte", "empresa" : "4Linux" }
{ "_id" : ObjectId("58a747b644f122d1903c5522"), "nome" : "Gabriel", "sobrenome" : "Bonfim", "cargo" : "Desenvolvedor Senior", "empresa" : "4Linux" }
> 


Caso queira agrupar os valores, é possível utilizando a instrução $group, essa instrução obrigatoriamente precisa que seja passado um _id e esse ai deve ser um campo do documento retornado.

Por exemplo:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$group":{"_id":"$nome"}}])
{ "_id" : "Gabriel" }
{ "_id" : "Mariana" }
{ "_id" : "Antonio" }
{ "_id" : "Alisson" }

Para ver o total de documentos agrupados, pode-se utilizar a instrução $sum:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$group":{"_id":"$empresa","total":{"$sum":1}}}])
{ "_id" : "4Linux", "total" : 4 }

Para contar todos os resultados sem o agrupamento, pode-se utilizar a instrução $count, essa instrução só existe a partir da versão 3.4:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$count":"total"}])

É possível também projetar uma saída, ou seja, modelar o documento e mostrar apenas campos específicos aumentando a performance da sua busca e trazendo resultados mais fáceis de se encontrar.

Por exemplo:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$project":{"nome":1,"cargo":1}}])
{ "_id" : ObjectId("58a7479844f122d1903c551f"), "nome" : "Alisson", "cargo" : "Analista de Sistemas DevOps" }
{ "_id" : ObjectId("58a747a144f122d1903c5520"), "nome" : "Mariana", "cargo" : "Analista de Sistemas DevOps" }
{ "_id" : ObjectId("58a747ac44f122d1903c5521"), "nome" : "Antonio", "cargo" : "Supervidor de Suporte" }
{ "_id" : ObjectId("58a747b644f122d1903c5522"), "nome" : "Gabriel", "cargo" : "Desenvolvedor Senior" }

O exemplo acima, pode-se ver que foi foram mostrados somente os campos _id, nome e cargo, sendo assim quando se quer mostrar um campo, coloca-se o valor 1 em conjunto com a chave, caso não queira pode se colocar o valor 0.

Por exemplo:

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$project":{"nome":1,"cargo":1,"_id":0}}])
{ "nome" : "Alisson", "cargo" : "Analista de Sistemas DevOps" }
{ "nome" : "Mariana", "cargo" : "Analista de Sistemas DevOps" }
{ "nome" : "Antonio", "cargo" : "Supervidor de Suporte" }
{ "nome" : "Gabriel", "cargo" : "Desenvolvedor Senior" }

No exemplo acima foi ocultado o campo _id para melhorar a visualização do documento.

O Aggregation do MongoDB trabalha com um esquema de pipeline, ou seja, você pode concatenar todas as instruções juntas.

Por exemplo:

Pode-se fazer um $match, depois um $project para limitar os campos e depois um $group para agrupar pelos cargo e saber quantas pessoas daquela posição existem na empresa.

> db.funcionarios.aggregate([{"$match":{"empresa":"4Linux"}},{"$project":{"nome":1,"cargo":1,"_id":0}},{"$group":{"_id":"$cargo","total":{"$sum":1}}}])
{ "_id" : "Desenvolvedor Senior", "total" : 1 }
{ "_id" : "Supervidor de Suporte", "total" : 1 }
{ "_id" : "Analista de Sistemas DevOps", "total" : 2 }

Esses são os comandos básicos para fazer um Aggregate no MongoDB. Espero que ajude em seus projetos.

MongoDB Aggregation

Anterior Software Livre não é software, é serviço
Próxima Zend: a ferramenta certa para o trabalho certo!

About author

Alisson Machado
Alisson Machado 15 posts

Alisson Menezes, atua como Gerente de T.I, 9 anos de experiência em projetos FOSS (Free and Open Source Software) e Python. Formação em Análise de Sistemas pela FMU e cursando MBA em BigData pela FIA, possui certificações LPI1, LPI2 e SUSE CLA, LPI DevOps e Exim - DevOps Professional. Autor dos cursos Python Fundamentals, Python for Sysadmins, MongoDB for Developers/DBAs, DevSecOps, Co-Autor do Infraestrutura Ágil e Docker da 4Linux e palestrantes em eventos como FISL, TDC e Python Brasil. É entusiasta das mais diversas áreas em T.I como Segurança, Bancos de dados NoSQL, DataScience mas tem como foco DevOps e Automação.

View all posts by this author →

Você pode gostar também

Infraestrutura

Instalação do Cuda 9 em distribuições Linux baseadas no Ubuntu

Se você deseja trabalhar com algoritmos de Machine Learning, provavelmente precisará usar processamento paralelo para acelerar os resultados dos seus algoritmos. Muitos frameworks como por exemplo, o TensorFlow, já possuem

Infraestrutura

MongoDB: como criar um Cluster Replication Set

O MongoDB é um banco com foco em escalabilidade horizontal, sendo assim ele possui um recurso chamado ReplicatSet que serve para replicar os dados em um cluster de servidores para

Infraestrutura

Vault: Autenticação SSH com OneTime Password

Vault é uma ferramenta desenvolvida pela HashiCorp, essa ferramenta tem como objetivo fazer um armazenamento inteligente de “segredos”, podem ser eles, chaves de ssh, dados de acesso a um banco