Enlazar Documentos de MongoDB

MongoDBBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá los fundamentos para establecer relaciones entre documentos en MongoDB. Esta técnica, conocida como referenciación (referencing), es esencial para construir estructuras de bases de datos complejas y organizadas. Practicará la creación de colecciones, la inserción de documentos con referencias a otros documentos, la recuperación y combinación de datos relacionados utilizando la etapa de agregación $lookup, y la gestión del ciclo de vida de estos documentos enlazados. Al finalizar este laboratorio, tendrá una sólida comprensión de cómo modelar y gestionar relaciones de uno a muchos (one-to-many) en su base de datos MongoDB.

Este es un Guided Lab, que proporciona instrucciones paso a paso para ayudarte a aprender y practicar. Sigue las instrucciones cuidadosamente para completar cada paso y obtener experiencia práctica. Los datos históricos muestran que este es un laboratorio de nivel principiante con una tasa de finalización del 100%. Ha recibido una tasa de reseñas positivas del 100% por parte de los estudiantes.

Establecer Relaciones entre Documentos

En este primer paso, creará dos colecciones separadas y establecerá una relación entre ellas. Modelaremos un escenario común: una base de datos de biblioteca con authors (autores) y books (libros). Cada libro hará referencia a su autor.

Primero, abra la MongoDB Shell. Esta interfaz interactiva de línea de comandos le permite interactuar con su instancia de MongoDB.

mongosh

Una vez dentro de la shell, verá un prompt test>. Cambiemos a una nueva base de datos llamada library_database. Si la base de datos no existe, MongoDB la creará por usted cuando almacene datos por primera vez.

use library_database

Ahora, creemos la colección authors insertando dos documentos. Cada documento tiene un _id único de tipo ObjectId, que utilizaremos para la referenciación.

db.authors.insertMany([
  {
    _id: ObjectId("660a1f5c9b8f8b1234567890"),
    name: "Jane Austen",
    nationality: "British"
  },
  {
    _id: ObjectId("660a1f5c9b8f8b1234567891"),
    name: "George Orwell",
    nationality: "British"
  }
]);

Debería ver una confirmación de que los documentos se insertaron correctamente.

Ejemplo de salida:

{
  "acknowledged": true,
  "insertedIds": {
    "0": ObjectId("660a1f5c9b8f8b1234567890"),
    "1": ObjectId("660a1f5c9b8f8b1234567891")
  }
}

A continuación, cree la colección books. En cada documento de libro, el campo author_id almacenará el ObjectId del autor correspondiente de la colección authors. Esto crea el enlace entre un libro y su autor.

db.books.insertMany([
  {
    title: "Pride and Prejudice",
    author_id: ObjectId("660a1f5c9b8f8b1234567890"),
    year: 1813
  },
  {
    title: "1984",
    author_id: ObjectId("660a1f5c9b8f8b1234567891"),
    year: 1949
  }
]);

Ejemplo de salida:

{
  "acknowledged": true,
  "insertedIds": {
    "0": ObjectId("660b2a1c9b8f8b1234567892"),
    "1": ObjectId("660b2a1c9b8f8b1234567893")
  }
}

Ahora ha creado con éxito dos colecciones y enlazado documentos en la colección books con documentos en la colección authors. Mantenga la shell de MongoDB abierta para el siguiente paso.

Consultar Documentos Enlazados

Ahora que ha establecido las relaciones, el siguiente paso lógico es recuperar los datos enlazados en una única consulta. El framework de agregación de MongoDB proporciona la etapa $lookup para este propósito, la cual realiza un join externo izquierdo (left outer join) a otra colección.

Asegúrese de que todavía está en la shell mongosh y utilizando la library_database.

Realicemos una consulta para obtener todos los libros e incrustar la información de su autor correspondiente dentro de los resultados.

db.books.aggregate([
  {
    $lookup: {
      from: "authors",
      localField: "author_id",
      foreignField: "_id",
      as: "author_details"
    }
  }
]);

La etapa $lookup une la colección books con la colección authors. Revisemos sus parámetros:

  • from: "authors": Especifica la colección con la que se realizará el join.
  • localField: "author_id": Especifica el campo de los documentos de entrada (de la colección books).
  • foreignField: "_id": Especifica el campo de los documentos de la colección "from" (la colección authors).
  • as: "author_details": Especifica el nombre del nuevo campo de array que se añadirá a la salida. Este array contendrá los documentos de autor coincidentes.

Ejemplo de salida para uno de los documentos:

[
  {
    "_id": ObjectId("..."),
    "title": "Pride and Prejudice",
    "author_id": ObjectId("660a1f5c9b8f8b1234567890"),
    "year": 1813,
    "author_details": [
      {
        "_id": ObjectId("660a1f5c9b8f8b1234567890"),
        "name": "Jane Austen",
        "nationality": "British"
      }
    ]
  },
  ...
]

Como puede ver, el campo author_details es un array que contiene el documento completo del autor. Esta potente característica le permite recuperar datos completos sin necesidad de realizar múltiples consultas desde su aplicación.

Actualizar Documentos Relacionados

Los datos en una base de datos rara vez son estáticos. En este paso, aprenderá cómo actualizar documentos tanto en las colecciones authors como books. Dado que estamos utilizando referencias, puede actualizar la información de un autor en un lugar, y todas las consultas que se unan con ese autor reflejarán automáticamente el cambio.

Agreguemos un año de nacimiento al documento de Jane Austen. Utilizaremos el método updateOne con el operador $set para agregar un nuevo campo sin sobrescribir el documento completo.

db.authors.updateOne(
  { name: "Jane Austen" },
  {
    $set: {
      birth_year: 1775
    }
  }
);

Ejemplo de salida:

{
  "acknowledged": true,
  "insertedId": null,
  "matchedCount": 1,
  "modifiedCount": 1,
  "upsertedCount": 0
}

Ahora, actualicemos los detalles de un libro. Agregaremos un genre (género) a "Pride and Prejudice".

db.books.updateOne(
  { title: "Pride and Prejudice" },
  {
    $set: {
      genre: "Romance"
    }
  }
);

Para verificar que ambas actualizaciones fueron exitosas, puede consultar los documentos directamente.

Primero, verifique el autor:

db.authors.findOne({ name: "Jane Austen" });

Luego, verifique el libro:

db.books.findOne({ title: "Pride and Prejudice" });

Verá los nuevos campos birth_year y genre en los documentos respectivos. La referencia author_id en el documento del libro permanece sin cambios, preservando el enlace.

Gestionar y Eliminar Enlaces de Documentos

La parte final de la gestión de relaciones es el manejo de las eliminaciones. Cuando elimina un documento, debe considerar qué sucede con los documentos que lo referencian. MongoDB no aplica la integridad referencial automáticamente, por lo que esta es una tarea que debe gestionar a nivel de aplicación.

Primero, eliminemos un libro manteniendo a su autor. Eliminaremos el libro "1984".

db.books.deleteOne({ title: "1984" });

Ejemplo de salida:

{ "acknowledged": true, "deletedCount": 1 }

Si ahora consulta la colección books, verá que solo queda un libro. El documento "George Orwell" en la colección authors no se ve afectado.

Ahora, consideremos un escenario más complejo: eliminar un autor y todos sus libros asociados. Esto requiere un proceso de varios pasos para mantener la integridad de los datos.

Primero, encuentre el ID del autor y guárdelo en una variable. Eliminaremos a "Jane Austen".

const authorId = db.authors.findOne({ name: "Jane Austen" })._id;

A continuación, utilice este ID para eliminar todos los libros asociados con ese autor. El comando deleteMany se utiliza en caso de que un autor tenga varios libros.

db.books.deleteMany({ author_id: authorId });

Finalmente, elimine el propio documento del autor.

db.authors.deleteOne({ _id: authorId });

Este proceso manual y de varios pasos garantiza que no deje documentos de libros "huérfanos" con referencias author_id inválidas. Puede verificar que tanto el libro "Pride and Prejudice" como el autor "Jane Austen" han sido eliminados de sus respectivas colecciones.

Ahora puede salir de la shell de MongoDB.

exit

Resumen

En este laboratorio, ha aprendido las técnicas esenciales para trabajar con documentos enlazados en MongoDB. Comenzó creando las colecciones authors y books y estableciendo una relación de uno a muchos utilizando referencias de documentos. Luego practicó cómo recuperar y combinar datos de estas colecciones relacionadas utilizando la etapa de agregación $lookup. Además, aprendió cómo actualizar documentos individuales sin romper sus enlaces y, finalmente, cómo gestionar adecuadamente las eliminaciones para mantener la integridad de los datos eliminando documentos relacionados en un proceso controlado y de varios pasos. Estas habilidades forman una base sólida para diseñar y construir aplicaciones de bases de datos NoSQL más sofisticadas e interconectadas.