HOWTO · MongoDB
Proyectar campos anidados en MongoDB
Aprende a seleccionar campos anidados de MongoDB con la notación de puntos y find(), dar forma a los resultados de una agregación con $project y eliminar campos con $unset.
En esta página
Los documentos de MongoDB pueden contener documentos incrustados, como un objeto address dentro del registro de un usuario. Una proyección controla qué campos devuelve una consulta. Por ejemplo, seleccionar address.city devuelve ese valor anidado y conserva su estructura. Usa la proyección de find() para obtener un resultado de consulta sencillo, $project para dar forma a documentos en una canalización de agregación y $unset para eliminar campos seleccionados de los resultados de la canalización.
Comprender la proyección de campos anidados en MongoDB
Supongamos que un documento tiene los campos name y address, y que address contiene street, city y country. Una ruta anidada usa notación de puntos, como address.city. La proyección modifica el documento devuelto; no modifica el documento de origen almacenado. Los ejemplos siguientes usan esta misma estructura. En las proyecciones de find(), _id se incluye de forma predeterminada, salvo que se excluya explícitamente.
Usar la notación de puntos con find() para seleccionar campos anidados
Para devolver solo la ciudad de la dirección anidada, incluye su ruta con puntos. Esta expresión de shell de MongoDB ilustra la sintaxis y no se ejecuta en el entorno configurado:
db.users.find({}, { "address.city": 1, "_id": 0 })
La estructura devuelta es { "address": { "city": "New York" } }. Omite _id: 0 si quieres que cada resultado conserve el identificador. Para excluir una ruta anidada y mantener los demás campos, usa 0, como en { "address.country": 0 }.
Por lo general, una proyección de inclusión no puede combinar campos incluidos y excluidos. La excepción es _id: se puede excluir mientras se incluyen otras rutas. Para los demás campos, elige una proyección de inclusión o una de exclusión.
Ejecuta este ejemplo:
El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.
document = {"name": "Ava", "address": {"city": "New York", "country": "USA"}}
result = {"address": {"city": document["address"]["city"]}}
print(result)
{'address': {'city': 'New York'}}
Este pequeño ejemplo de Python ilustra la estructura anidada devuelta; no se conecta a MongoDB. La salida muestra un objeto con address.city establecido en New York. El código y las etiquetas o salidas visibles de este ejemplo se conservan en inglés por la paridad con el original. La consulta de MongoDB anterior usa la ruta con puntos correspondiente.
Usar la etapa de agregación $project para dar forma a campos anidados
En una canalización de agregación, $project puede incluir rutas anidadas y asignar rutas de origen a campos de salida. Por ejemplo, { $project: { _id: 0, city: "$address.city", name: 1 } } devuelve city en el nivel superior, junto a name. En cambio, una inclusión directa de ruta, como { $project: { "address.city": 1, _id: 0 } }, conserva el anidamiento address.city. Esto hace que $project sea útil cuando la canalización necesita una estructura de salida específica. Las expresiones también pueden calcular valores de salida; asegúrate de que cada expresión haga referencia a un campo presente en los documentos de entrada.
Usar la etapa de agregación $unset para excluir campos anidados
Usa la etapa de agregación $unset para eliminar una o varias rutas y conservar los demás campos: { $unset: ["address.country"] }. Una ruta con puntos elimina ese campo anidado del resultado de la canalización. $unset cambia qué campos continúan por la canalización; no filtra documentos. Para filtrar documentos, usa una condición de consulta o una etapa $match. Esta etapa es una función de agregación, distinta del operador de actualización que tiene el mismo nombre.
Elegir entre la proyección de consulta y la agregación
Usa find() con notación de puntos cuando una consulta solo necesite incluir o excluir campos de los documentos devueltos. Elige $project cuando una agregación deba cambiar el nombre de rutas, calcular valores o definir una estructura de salida concreta. Elige $unset cuando la canalización deba conservar la mayoría de los campos y eliminar unos pocos. $addFields añade o reemplaza campos y conserva el resto del documento, por lo que no sustituye a la selección de una proyección. En los tres casos, la proyección o la transformación de campos afecta a los resultados, no a los documentos almacenados.