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.
About author
Você pode gostar também
Guia completo sobre PromQL: a linguagem de consulta do Prometheus
Nesse post vamos falar sobre o PromQL, que nada mais é do que uma linguagem de consulta do Prometheus, ela nos possibilita selecionar e agregar dados de séries temporais em
Guia passo a passo para configurar um ReplicatSet no MongoDB
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
Como versionar sua infraestrutura com Terraform e GitLab
Deixando um pouco o assunto sobre Corona Vírus de lado, chegamos ao penúltimo post da nossa série de postagens sobre Terraform. Aqui iremos falar sobre como versionar sua infraestrutura utilizando