Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

Evitar el arreglo ilimitado

Almacenar arreglos como valores de campo te permite integrar datos y asegurarte de que los datos que se acceden juntos se almacenen juntos. Sin embargo, si no se limita el número de elementos en un arreglo, los documentos pueden exceder el Límite de tamaño del documento BSON de16MB. Un arreglo sin límites puede agotar los recursos de una aplicación y disminuir el rendimiento del índice.

En lugar de incrustar conjuntos de datos completos, utiliza subconjuntos y referencias a arreglos limitados, lo que puede mejorar el rendimiento y mantener dentro de límites el tamaño de los documentos. Al seleccionar subconjuntos de datos, sólo se eligen las partes necesarias de los datos posteriores con los que se van a trabajar, lo que reduce el uso de memoria y el tiempo de procesamiento al centrarse solo en los datos relevantes. Cuando haces referencia a datos, conectas con fuentes de datos externas en lugar de incrustarlas directamente en tus documentos. Este enfoque mejora el rendimiento y reduce el tamaño del documento. Al utilizar subsetting y referencia, puedes limitar arreglos y administrar tus fechas de manera más eficiente.

Considera el siguiente esquema que rastrea las reseñas de libros para una aplicación de librería. El esquema inicial usa un arreglo para el reviews .

{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: [
{
user: "Alice",
review: "Great book!",
rating: 5
},
{
user: "Bob",
review: "Didn't like it!",
rating: 1
},
{
user: "Charlie",
review: "Not bad, but could be better.",
rating: 3
}
]
}

En este esquema, el campo reviews es un arreglo ilimitado. Cada vez que se crea una nueva revisión para este libro, la aplicación agrega un nuevo subdocumento al arreglo reviews. A medida que se añaden más reseñas, el arreglo puede crecer demasiado y poner en riesgo los recursos de la aplicación.

En este ejemplo, la aplicación de librería solo debe mostrar tres revisiones por libro. Para evitar arreglos sin límites, puedes utilizar el patrón de diseño de subconjuntos o referencias de documentos, dependiendo del caso de uso.

El submuestreo de datos es mejor cuando se necesita un acceso rápido a datos que no se actualizan con frecuencia. Utilizando el patrón de subconjunto, se pueden incorporar tres de las reseñas en el documento del libro para obtener toda la información necesaria en una sola operación. Las otras reseñas se almacenan en una colección reviews separada. Este patrón de diseño de esquema proporciona los siguientes beneficios:

  • Se elimina el arreglo no limitado

  • Controlar el tamaño del documento

  • Evite el uso de múltiples queries

La colección books:

db.books.insertOne( [
{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: [
{
reviewer: "Alice",
review: "Great book!",
rating: 5
},
{
reviewer: "Charlie",
review: "Didn't like it.",
rating: 1
},
{
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
}
],
}
] )

La colección reviews:

db.reviews.insertMany( [
{
reviewer: "Jason",
review: "Did not enjoy!",
rating: 1
},
{
reviewer: "Pam",
review: "Favorite book!",
rating: 5
},
{
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
}
] )

Este enfoque duplica datos, lo que hace que las actualizaciones sean costosas. Este enfoque es el mejor si las revisiones no se actualizan con frecuencia.

Hacer referencia a datos es lo mejor cuando necesita administrar conjuntos de datos grandes o frecuentemente actualizados sin aumentar el tamaño de los documentos.

Para hacer referencia a los datos, almacena reseñas en una colección por separado y añade un campo review_id a los documentos en la colección reviews. Utiliza el campo review_id para hacer referencia a las revisiones en la colección books.

Este enfoque resuelve el problema del arreglo ilimitado, pero introduce latencia porque necesitas consultar la colección reviews para obtener información de reseñas para la colección books. Dependiendo del caso de uso, esta latencia adicional puede ser un intercambio aceptable para evitar los problemas causados por arreglos ilimitados.

La colección books:

db.books.insertMany( [
{
title: "Harry Potter",
author: "J.K. Rowling",
publisher: "Scholastic",
reviews: ["review1", "review2", "review3"]
},
{
title: "Pride and Prejudice",
author: "Jane Austen",
publisher: "Penguin",
reviews: ["review4", "review5"]
}
] )

La colección reviews:

db.reviews.insertMany( [
{
review_id: "review1",
reviewer: "Jason",
review: "Did not enjoy!",
rating: 1
},
{
review_id: "review2",
reviewer: "Pam",
review: "Favorite book!",
rating: 5
},
{
review_id: "review3",
reviewer: "Bob",
review: "Not bad, but could be better.",
rating: 3
},
{
review_id: "review4",
reviewer: "Tina",
review: "Amazing!",
rating: 5
},
{
review_id: "review5",
reviewer: "Jacob",
review: "A little overrated",
rating: 4,
}
] )

Si tu información de books y reviews está almacenada en colecciones separadas, la aplicación necesita realizar una operación de $lookup para unir los datos.

La siguiente operación de agregación une las colecciones books y reviews del ejemplo anterior.

db.books.aggregate( [
{
$lookup: {
from: "reviews",
localField: "reviews",
foreignField: "review_id",
as: "reviewDetails"
}
}
] )

La operación devuelve lo siguiente:

[
{
_id: ObjectId('665de81eeda086b5e22dbcc9'),
title: 'Harry Potter',
author: 'J.K. Rowling',
publisher: 'Scholastic',
reviews: [ 'review1', 'review2', 'review3' ],
reviewDetails: [
{
_id: ObjectId('665de82beda086b5e22dbccb'),
review_id: 'review1',
reviewer: 'Jason',
review: 'Did not enjoy!',
rating: 1
},
{
_id: ObjectId('665de82beda086b5e22dbccc'),
review_id: 'review2',
reviewer: 'Pam',
review: 'Favorite book!',
rating: 5
},
{
_id: ObjectId('665de82beda086b5e22dbccd'),
review_id: 'review3',
reviewer: 'Bob',
review: 'Not bad, but could be better.',
rating: 3
} ]
},
{
_id: ObjectId('665de81eeda086b5e22dbcca'),
title: 'Pride and Prejudice',
author: 'Jane Austen',
publisher: 'Penguin',
reviews: [ 'review4', 'review5' ],
reviewDetails: [
{
_id: ObjectId('665de82beda086b5e22dbcce'),
review_id: 'review4',
reviewer: 'Tina',
review: 'Amazing!',
rating: 5
},
{
_id: ObjectId('665de82beda086b5e22dbccf'),
review_id: 'review5',
reviewer: 'Jacob',
review: 'A little overrated',
rating: 4
} ]
}
]

En este ejemplo, la operación $lookup une la colección books con la colección reviews utilizando el arreglo reviews en el documento del libro y el campo review_id en los documentos de reseñas. El documento reviewDetails almacena los datos combinados.

Volver

Antipatrones de diseño de esquemas

Obtén una insignia de habilidad

¡Domina "Patrones y antipatrones de diseño de esquemas" de forma gratuita!

Más información

En esta página