Overview
Esta página describe un modelo de datos que utiliza Documentos incrustados para describir una relación uno a muchos entre datos conectados. Incrustar datos conectados en un solo documento puede reducir el número de operaciones de lectura necesarias para obtenerlos. En general, debe estructurar su esquema de modo que su aplicación reciba toda la información necesaria en una sola operación de lectura.
Patrón de Documento Incrustado
Considere el siguiente ejemplo que mapea relaciones de usuario y múltiples direcciones. El ejemplo ilustra la ventaja de la incrustación sobre la referencia si necesita ver muchas entidades de datos en el contexto de otra. En esta relación uno a muchos entre patron y address datos, el patron tiene múltiples entidades address.
En el modelo de datos normalizado, los documentos address contienen una referencia al documento patron.
// patron document { _id: "joe", name: "Joe Bookreader" } // address documents { patron_id: "joe", // reference to patron document street: "123 Fake Street", city: "Faketon", state: "MA", zip: "12345" } { patron_id: "joe", street: "1 Some Other Street", city: "Boston", state: "MA", zip: "12345" }
Si su aplicación recupera frecuentemente los datos address con la información name, deberá ejecutar múltiples consultas para resolver las referencias. Un esquema más óptimo sería incrustar las entidades de datos address en los datos patron, como se muestra en el siguiente documento:
{ _id: "joe", name: "Joe Bookreader", addresses: [ { street: "123 Fake Street", city: "Faketon", state: "MA", zip: "12345" }, { street: "1 Some Other Street", city: "Boston", state: "MA", zip: "12345" } ] }
Con el modelo de datos embebido, tu aplicación puede recuperar la información completa del cliente con una sola query.
Patrón de subconjunto
Un problema potencial con el patrón de documento incrustado es que puede generar documentos extensos, especialmente si el campo incrustado no tiene límites. En este caso, se puede usar el patrón de subconjunto para acceder únicamente a los datos que requiere la aplicación, en lugar de a todo el conjunto de datos incrustados.
Considere un sitio de comercio electrónico que tiene una lista de reseñas de un producto:
{ "_id": 1, "name": "Super Widget", "description": "This is the most useful item in your toolbox.", "price": { "value": NumberDecimal("119.99"), "currency": "USD" }, "reviews": [ { "review_id": 786, "review_author": "Kristina", "review_text": "This is indeed an amazing widget.", "published_date": ISODate("2019-02-18") }, { "review_id": 785, "review_author": "Trina", "review_text": "Nice product. Slow shipping.", "published_date": ISODate("2019-02-17") }, ... { "review_id": 1, "review_author": "Hans", "review_text": "Meh, it's okay.", "published_date": ISODate("2017-12-06") } ] }
Las reseñas se ordenan en orden cronológico inverso. Cuando un usuario visita la página de un producto, la aplicación carga las diez reseñas más recientes.
En lugar de almacenar todas las reseñas junto con el producto, puedes dividir la colección en dos colecciones:
La colección
productalmacena información sobre cada producto, incluidas las diez reseñas más recientes del producto:{ "_id": 1, "name": "Super Widget", "description": "This is the most useful item in your toolbox.", "price": { "value": NumberDecimal("119.99"), "currency": "USD" }, "reviews": [ { "review_id": 786, "review_author": "Kristina", "review_text": "This is indeed an amazing widget.", "published_date": ISODate("2019-02-18") } ... { "review_id": 777, "review_author": "Pablo", "review_text": "Amazing!", "published_date": ISODate("2019-02-16") } ] } La colección
reviewalmacena todas las revisiones. Cada revisión contiene una referencia al producto para el cual fue escrita.{ "review_id": 786, "product_id": 1, "review_author": "Kristina", "review_text": "This is indeed an amazing widget.", "published_date": ISODate("2019-02-18") } { "review_id": 785, "product_id": 1, "review_author": "Trina", "review_text": "Nice product. Slow shipping.", "published_date": ISODate("2019-02-17") } ... { "review_id": 1, "product_id": 1, "review_author": "Hans", "review_text": "Meh, it's okay.", "published_date": ISODate("2017-12-06") }
Al almacenar las diez reseñas más recientes en la colección product, solo se devuelve el subconjunto requerido de los datos generales al llamar a la colección product. Si un usuario desea ver más reseñas, la aplicación llama a la colección review.
Tip
Al considerar dónde dividir los datos, la parte a la que se accede con más frecuencia debe ir en la colección que la aplicación carga primero. En este ejemplo, el esquema se divide en diez revisiones, ya que ese es el número de revisiones visibles en la aplicación por defecto.
Tip
Para aprender a utilizar el patrón de subconjunto para modelar relaciones uno a uno entre colecciones, consulte Modelar relaciones uno a uno con documentos integrados.
Compensaciones del patrón de subconjunto
El uso de documentos más pequeños que contienen datos de acceso más frecuente reduce el tamaño total del conjunto de trabajo. Estos documentos más pequeños mejoran el rendimiento de lectura de los datos a los que la aplicación accede con mayor frecuencia.
Sin embargo, el patrón de subconjuntos genera datos duplicados. En el ejemplo, las reseñas se mantienen tanto en la colección product como en la reviews. Se deben tomar medidas adicionales para garantizar que las reseñas sean consistentes en cada colección. Por ejemplo, cuando un cliente edita su reseña, la aplicación podría necesitar realizar dos operaciones de escritura: una para actualizar la colección product y otra para actualizar la colección reviews.
También debe implementar lógica en su aplicación para garantizar que las reseñas en la colección product sean siempre las diez reseñas más recientes para ese producto.
Otros casos de uso de muestra
Además de las reseñas de productos, el patrón de subconjunto también puede ser una buena opción para almacenar:
Comentarios en una publicación de blog, cuando solo desea mostrar los comentarios más recientes o mejor calificados de forma predeterminada.
Miembros del reparto en una película, cuando solo desea mostrar a los miembros del reparto con los papeles más importantes de forma predeterminada.