Curso
Si acabas de empezar a trastear con MongoDB, seguramente ya te has topado con documentos cada vez más complejos. Quizá han pasado de ser datos planos, con aire relacional, a tener objetos anidados, arrays anidados e incluso cuatro o cinco niveles de anidamiento. Entonces, ¿cómo consultas estos datos cuando están a varias capas de profundidad?
En este tutorial breve veremos la notación con puntos en MongoDB y cómo filtrar rápida y fácilmente nuestros documentos en función de valores presentes en campos anidados.
Cuando hablamos de notación con puntos, nos referimos a separar los campos anidados con el carácter punto. Por ejemplo:
root_field.nested_field_1.next_layer_nested_field_1
Por cada nivel de anidamiento, añadimos un punto que separa ese nivel al hacer la consulta. Veremos ejemplos más detallados a medida que avancemos en el tutorial.
Si estás empezando con MongoDB, echa un vistazo al curso Introduction to MongoDB in Python de DataCamp.
Requisitos previos
Para seguir este tutorial con éxito, necesitas tener una instancia de MongoDB desplegada y configurada. Es decir, se da por hecho que ya estás listo para empezar a usar MongoDB. También deberías tener, como mínimo, cierta familiaridad con las consultas a colecciones en MongoDB. La documentación puede ser un buen punto de partida si necesitas ayuda.
Para este ejemplo, usaremos los siguientes datos dentro de la base de datos "dbinc" y la colección "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
}
}
}
]
Estos datos representan dos documentos con un nivel de complejidad razonable por sus objetos y arrays anidados. Como curiosidad, MongoDB permite más de 100 niveles de anidamiento en documentos BSON.
Si vas a seguir el tutorial paso a paso, asegúrate de que estos documentos existen en tu instancia de MongoDB.
Consulta de datos en MongoDB con diferentes enfoques
Empezaremos con algo sencillo y avanzaremos poco a poco hacia casos más complejos. La buena noticia es que complejo no significa necesariamente difícil.
Imagina que queremos encontrar a todas las personas de la colección que trabajan en MongoDB. Podríamos ejecutar una consulta como esta:
use dbinc;
db.people.find({
"employment.employer": "MongoDB"
});
En este ejemplo, employer es un campo anidado dentro del objeto employment. Podemos consultarlo con notación con puntos, es decir, campos separados por puntos. No es distinto de, por ejemplo, buscar a todas las personas que trabajan en New York. Podríamos hacer algo así:
use dbinc;
db.people.find({
"employment.address.state": "New York"
});
En la consulta anterior hemos llegado a tres niveles de profundidad en el documento, y funciona sin problema.
Ahora, veamos cómo trabajar con ese array anidado de objetos. Hay varias formas de consultar, según lo que queramos conseguir.
Supongamos que queremos devolver a todas las personas que tienen un sitio web "Portfolio". Podríamos ejecutar una consulta como esta:
use dbinc;
db.people.find({
"websites.name": "Portfolio"
});
Esta consulta devolvería un único resultado porque solo uno de los documentos tiene un "Portfolio". Fíjate en que, aunque sea un array, la notación con puntos sigue funcionando. El matiz es que "Portfolio" debe existir al menos una vez en ese array.
Aquí es donde se pone interesante.
Imagina que queremos acotar aún más los resultados. Añadiríamos más criterios de filtro, pero cuando trabajamos con objetos anidados dentro de arrays, la cosa cambia un poco. Por ejemplo:
use dbinc;
db.people.find({
"websites.name": "Portfolio",
"websites.type": "social"
});
En el ejemplo anterior, estamos diciendo que queremos resultados en los que existan "Portfolio" y "social" en el array, pero no necesariamente en el mismo objeto. Solo obtenemos un resultado porque el documento de "Tony Kim" tiene "social", pero no "Portfolio". Si necesitáramos que ambos campos existieran en el mismo objeto del array, la notación con puntos no sería suficiente.
Aunque se sale del alcance de este tutorial, el operador $elemMatch resuelve este caso así:
use dbinc;
db.people.find(
{
"websites": {
"$elemMatch": {
"name": "Portfolio",
"type": "social"
}
}
}
);
En este caso no se devolverían resultados porque nuestros datos de ejemplo no tienen un name y un type coincidentes dentro del mismo objeto.
Si trabajas con arrays y conoces el índice del elemento que quieres usar, puedes seguir utilizando la notación con puntos. Por ejemplo:
use dbinc;
db.people.find({
"websites.0.name": "Portfolio"
});
Aquí usamos el índice del array contra el que queremos hacer la coincidencia. En este escenario, queremos devolver todos los documentos donde el primer elemento del array tenga un name igual a "Portfolio".
Aunque quede fuera del alcance de este tutorial, conviene señalar que la notación con puntos no se limita a consultas de lectura. Puedes usarla también en operaciones de actualización, proyecciones y pipelines de agregación.
Conclusión
Acabas de ver una introducción rápida al uso de la notación con puntos en tus consultas de MongoDB. Hemos aprendido que:
- La notación con puntos funciona con objetos anidados.
- Puedes usar notación con puntos en arrays, aunque con limitaciones según lo que esperes de esos arrays.
- Si quieres hacer coincidir varios campos dentro del mismo objeto del array, necesitas el operador
$elemMatch. - Puedes usar índices de array en la notación con puntos para consultar elementos concretos de un array.
Los datos de tus colecciones de MongoDB probablemente no serán planos; llegarás a tener objetos anidados, arrays anidados, arrays dentro de objetos y un sinfín de combinaciones. La buena noticia es que MongoDB facilita trabajar con esta información gracias a su potente API de consultas.
Si aún no usas MongoDB, echa un vistazo a MongoDB Atlas o a mi otro tutorial donde te muestro cómo empezar con MongoDB y Docker. Además, puedes informarte sobre la MongoDB Certification en nuestra guía aparte.
FAQs
¿Qué es la notación con puntos en MongoDB?
La notación con puntos consiste en acceder a campos anidados de documentos de MongoDB utilizando el delimitador punto.
¿Puedo filtrar con numerosos campos anidados en mis consultas?
Sí. Tus consultas de coincidencia pueden usar notación con puntos en todos, algunos o ninguno de tus campos. Es el mismo filtro: solo estás accediendo a elementos anidados.
¿Qué hago con mis arrays impredecibles?
Asegúrate de que tus arrays no crezcan sin límite por cuestiones de tamaño y rendimiento, pero consultarlos con notación con puntos funciona bien y sigue siendo sencillo.
¿Y si necesito actualizar un documento con objetos y arrays anidados?
En una operación de actualización, la notación con puntos funciona tanto en la parte del filtro como en la parte de los cambios.

