Curso
Se você está começando a explorar o MongoDB, provavelmente já chegou a um ponto em que seus documentos ficaram um pouco complexos. Eles podem ter deixado de ser dados "achatados", com cara de relacional, para incluir objetos aninhados, arrays aninhados e talvez quatro ou cinco níveis de aninhamento. Então, como consultar esses dados quando há várias camadas?
Neste tutorial rápido, vamos ver a notação por ponto no MongoDB e como filtrar documentos de forma simples e ágil com base em valores presentes em campos aninhados.
Quando falamos em notação por ponto, estamos nos referindo à separação de campos aninhados usando o caractere ponto. Por exemplo:
root_field.nested_field_1.next_layer_nested_field_1
Para cada nível de aninhamento, basta adicionar um ponto separando esse nível na consulta. Vamos ver exemplos mais completos ao longo do tutorial.
Se você está começando no MongoDB, confira o curso da DataCamp Introduction to MongoDB in Python.
Pré-requisitos
Para aproveitar este tutorial, você precisa ter uma instância do MongoDB implantada e configurada. Ou seja, a expectativa é que você já esteja pronto para usar o MongoDB. Também é importante ter pelo menos familiaridade básica com consultas a coleções no MongoDB. A documentação pode ser um bom ponto de partida, caso precise de ajuda.
Para este exemplo, vamos usar os dados abaixo no banco de dados "dbinc" e na coleção "people":
[
{
"name": "Nic Raboy",
"websites": [
{
"type": "other",
"name": "Portfolio",
"url": "https://www.nraboy.com"
},
{
"type": "social",
"name": "LinkedIn",
"url": "https://www.linkedin.com/in/nraboy"
}
],
"employment": {
"employer": "MongoDB",
"address": {
"street": "1633 Broadway",
"city": "New York",
"state": "New York",
"postal_code": 10019
}
}
},
{
"name": "Tony Kim",
"websites": [
{
"type": "social",
"name": "LinkedIn",
"url": "https://www.linkedin.com/in/hyung-kim/"
},
{
"type": "coding",
"name": "GitHub",
"url": "https://github.com/hjkmines"
}
],
"employment": {
"employer": "MongoDB",
"address": {
"street": "1633 Broadway",
"city": "New York",
"state": "New York",
"postal_code": 10019
}
}
}
]
Os dados acima representam dois documentos com um bom nível de complexidade, pois incluem objetos e arrays aninhados. Curiosidade: o MongoDB suporta mais de 100 níveis de aninhamento em documentos BSON.
Se você pretende acompanhar na prática, garanta que esses documentos existam na sua instância do MongoDB.
Consultando dados no MongoDB usando diferentes abordagens
Vamos começar simples e avançar aos poucos para casos mais elaborados. A boa notícia é que mais elaborado aqui não significa necessariamente mais difícil.
Digamos que queremos encontrar todas as pessoas na coleção que trabalham na MongoDB. Podemos executar uma consulta como esta:
use dbinc;
db.people.find({
"employment.employer": "MongoDB"
});
Neste exemplo, employer é um campo aninhado dentro do objeto employment. Podemos consultá-lo usando notação por ponto, que nada mais é do que campos separados por ponto. Não seria diferente se quiséssemos encontrar todas as pessoas que trabalham em New York. Poderíamos fazer algo assim:
use dbinc;
db.people.find({
"employment.address.state": "New York"
});
Na consulta acima, fomos três níveis dentro do documento, e funcionou sem problema.
Agora, vamos olhar para o array aninhado de objetos. Existem algumas formas de consultar, dependendo do objetivo.
Suponha que queremos retornar todas as pessoas que tenham um site "Portfolio" listado. Podemos executar uma consulta como esta:
use dbinc;
db.people.find({
"websites.name": "Portfolio"
});
Essa consulta retornaria um único resultado, porque apenas um dos documentos tem "Portfolio" listado. Perceba que, mesmo sendo um array, a notação por ponto ainda funcionou. O detalhe é que "Portfolio" precisa existir em algum lugar do array, pelo menos uma vez.
É aqui que a coisa fica interessante.
Digamos que queremos restringir ainda mais os resultados retornados. Faríamos isso adicionando mais critérios de filtro, mas, ao trabalhar com objetos aninhados dentro de arrays, há uma diferença. Veja o exemplo a seguir:
use dbinc;
db.people.find({
"websites.name": "Portfolio",
"websites.type": "social"
});
No exemplo acima, estamos dizendo que queremos resultados em que "Portfolio" e "social" existam no array, mas não necessariamente no mesmo objeto. Obtemos apenas um resultado porque o documento "Tony Kim" tem "social", mas não "Portfolio". Se precisarmos de resultados em que ambos os campos existam no mesmo objeto, não será possível usar apenas a notação por ponto.
Embora esteja fora do escopo deste tutorial, usar o operador $elemMatch desta forma resolve o problema:
use dbinc;
db.people.find(
{
"websites": {
"$elemMatch": {
"name": "Portfolio",
"type": "social"
}
}
}
);
Nenhum resultado seria retornado nesse cenário, porque nossos dados de exemplo não têm name e type correspondentes no mesmo objeto.
Se você estiver trabalhando com arrays e souber o índice do elemento desejado, pode continuar usando a notação por ponto. Por exemplo:
use dbinc;
db.people.find({
"websites.0.name": "Portfolio"
});
A consulta acima usa o índice do array que você quer verificar. Neste caso, queremos retornar todos os documentos em que o primeiro item do array tenha name igual a "Portfolio".
Também é importante destacar, mesmo fora do escopo deste tutorial, que a notação por ponto não se restringe a consultas de leitura. Você pode usá-la em operações de update, projeções e pipelines de agregação.
Conclusão
Você acabou de ver uma introdução rápida ao uso da notação por ponto em consultas no MongoDB. Vimos que:
- A notação por ponto funciona para objetos aninhados.
- Você pode usar notação por ponto com arrays, mas com limitações dependendo do que espera desses arrays.
- O operador
$elemMatché necessário quando você precisa corresponder a múltiplos campos dentro do mesmo objeto do array. - Índices de array na notação por ponto podem ser usados para consultar elementos específicos de um array.
Os dados nas suas coleções do MongoDB provavelmente não serão planos; em algum momento, você terá objetos aninhados, arrays aninhados, arrays dentro de objetos e outras combinações de complexidade. A boa notícia é que o MongoDB facilita trabalhar com tudo isso graças à sua API de consultas robusta.
Se você ainda não usa MongoDB, confira o MongoDB Atlas ou meu outro tutorial que mostra como começar com MongoDB e Docker. Você também pode conhecer a MongoDB Certification no nosso guia dedicado.
FAQs
O que é notação por ponto no MongoDB?
A notação por ponto é a forma de acessar campos aninhados de documentos do MongoDB usando o delimitador ponto.
Posso filtrar com vários campos aninhados nas minhas consultas?
Sim, suas consultas de correspondência podem usar notação por ponto em todos, alguns ou nenhum dos campos. É o mesmo filtro — você só está acessando itens aninhados.
O que fazer com arrays imprevisíveis?
Você deve garantir que seus arrays não sejam ilimitados por questões de tamanho e desempenho, mas consultá-los com notação por ponto funciona bem e continua simples.
E se eu precisar atualizar um documento com objetos e arrays aninhados?
Em operações de atualização (update), a notação por ponto funciona tanto na parte do filtro quanto na parte das alterações.

