Contenido del curso

Relaciones uno a uno con $lookup en MongoDB

Resumen

Modelar relaciones uno a uno referenciadas en MongoDB es la alternativa cuando un documento embebido se vuelve demasiado pesado y compromete el rendimiento. Aprenderás cuándo aplicar esta técnica, cómo conectar dos colecciones con un identificador común y cómo unirlas en una sola consulta usando $lookup.

¿Cuándo conviene usar una relación uno a uno referenciada?

La regla general en bases de datos documentales es embeber, pero hay un escenario claro donde esa práctica deja de funcionar.

MongoDB impone un límite de 16 MB por documento. Cuando empiezas a embeber demasiada información, te acercas a ese tope y, antes de alcanzarlo, las consultas se vuelven lentas porque el documento carga demasiado contenido. Ahí aparece la oportunidad de partir la información en otra colección y referenciarla.

¿Cuándo debo referenciar en vez de embeber un documento uno a uno? Cuando el documento crece tanto que ralentiza las consultas o se acerca al límite de 16 MB. En ese caso, divides la información en otra colección y la enlazas mediante un identificador común.

Un ejemplo típico: una colección stores con datos básicos como nombre, dirección y ciudad, y una colección separada stores_detail que guarda descripción, servicios y subdocumentos como la información del manager [1:18].

¿Cómo se enlazan dos colecciones en MongoDB?

El enlace se hace mediante un campo compartido entre ambos documentos. En el ejemplo de la clase, ese campo es store_id.

La colección stores guarda lo esencial de la tienda:

js db.stores.insertOne({ store_id: "ST001", name: "Nico Store Program", address: "Carlos 87" })

La colección stores_detail guarda el detalle conectado por el mismo store_id:

js db.stores_detail.insertOne({ store_id: "ST001", description: "texto texto texto", manager: { email: "nico@gmail.com", phone: "311..." } })

Fíjate que manager sigue siendo una relación uno a uno embebida dentro del detalle. Es decir, puedes mezclar ambas estrategias según convenga [3:45].

¿Cómo consulto datos enlazados sin hacer dos queries?

La forma directa es usar findOne en cada colección filtrando por store_id, pero eso implica dos consultas separadas. Para unificarlas en una sola operación, MongoDB ofrece el aggregation framework y, en particular, el operador $lookup.

¿Qué hace el operador $lookup en MongoDB?

$lookup es la herramienta que permite traer información de otra colección dentro de la misma consulta, simulando un join del mundo relacional pero adaptado al modelo documental.

La sintaxis sigue cuatro parámetros clave:

  • from: la colección destino que quieres enlazar.
  • localField: el campo de la colección actual que sirve como llave.
  • foreignField: el campo equivalente en la colección destino.
  • as: el nombre del array donde se guarda el resultado del enlace.

Aplicado al caso de las tiendas, la consulta queda así:

js db.stores.aggregate([ { $lookup: { from: "stores_detail", localField: "store_id", foreignField: "store_id", as: "detail" } } ])

Al ejecutar esto, obtienes el documento original de stores con un nuevo campo llamado detail, que contiene un array con los documentos coincidentes de stores_detail [6:30].

¿Qué devuelve $lookup? Devuelve el documento original más un campo nuevo en formato array con todos los documentos relacionados que cumplen la condición de enlace, aunque la relación sea uno a uno.

Es importante recordar que aunque la relación sea uno a uno, el resultado siempre llega como array. Tendrás que acceder al primer elemento si quieres tratarlo como objeto único.

¿Cuáles son los conceptos clave de esta técnica?

Antes de aplicar referencias en tus modelos, conviene tener clara la terminología que aparece en la clase:

  • Relación referenciada o enlazada: dos documentos en colecciones distintas conectados por un identificador común. También se le llama linked.
  • store_id como llave de enlace: un identificador de negocio que se replica en ambas colecciones para permitir el join.
  • Aggregation framework: el motor de consultas avanzadas de MongoDB que permite encadenar etapas como $lookup, $match o $group.
  • Límite de 16 MB: el tamaño máximo permitido por documento en MongoDB, razón principal para dividir información [0:35].
  • Subdocumento embebido dentro de un documento referenciado: como el manager dentro de stores_detail, demuestra que puedes combinar estrategias.

¿Embeber o referenciar en relaciones uno a uno?

La recomendación se mantiene: embeber primero, referenciar solo cuando el peso o el rendimiento lo exijan. La referencia es una solución a un problema concreto, no la opción por defecto en una base documental.

Si tu documento aún es liviano y las consultas responden rápido, embeber sigue siendo la mejor práctica. Cuando ya notas lentitud o el documento se acerca al límite, partirlo en dos colecciones con $lookup te devuelve velocidad sin perder la capacidad de consultar todo en una sola operación.

¿Has tenido que partir un documento por temas de rendimiento? Cuéntame en los comentarios cómo resolviste el modelado.