Guia prático: Como otimizar buscas no MongoDB com Aggregate

Guia prático: Como otimizar buscas no MongoDB com Aggregate

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 Conquiste melhores posições com a certificação Linux Essentials
Próxima Desvendando o Zend Framework 3: O guia definitivo para desenvolvedores PHP

About author

Alisson Machado
Alisson Machado 22 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

Desenvolvimento

Entenda o Processo de Consulta SQL no Sistema Gerenciador de Banco de Dados Postgres

Sempre que utilizamos o Sistema Gerenciador de Banco de Dados (SGBD) Postgres ou PostgreSQL, o foco principal de sua utilização é a realização de consultas (Querys), afinal de nada adiantaria

Cloud

Descubra o Jitsi: a solução completa para videoconferências

Logo do Jitsi Introdução Durante o momento que vivemos, basicamente todas nossas interações se tornaram virtuais, com o home office sendo a alternativa primaria para muitas empresas, tivemos um súbito

Cloud

Automatização de ambientes com Rundeck

Por que automatizar seu ambiente? Nos últimos anos, a automação tem crescido como um elemento imperativo em todos os negócios. Independente da área, temos observado um notável aumento no uso