Almacenar campos de datos que están relacionados entre sí, pero que no se acceden juntos puede crear documentos inflados que conducen a un uso excesivo de RAM y ancho de banda. El conjunto de trabajo, que consiste en datos e índices accedidos frecuentemente, se almacena en la asignación de RAM. Cuando el conjunto de trabajo cabe en la RAM, MongoDB puede realizar una query desde la memoria en lugar de desde el disco, lo que mejora el rendimiento. Sin embargo, si los documentos son demasiado grandes, el conjunto de trabajo podría no caber en la RAM, lo que provocaría una degradación del rendimiento, ya que MongoDB tendría que acceder a los datos desde el disco.
Para prevenir documentos hinchados, reestructura tu esquema con documentos más pequeños y utiliza referencias de documentos para separar campos que no se devuelven juntos. Este enfoque reduce el tamaño del conjunto de trabajo y mejora el rendimiento.
Acerca de esta tarea
Considera el siguiente esquema que contiene información de los libros utilizada en la página principal de un sitio web. La página principal solo muestra el título del libro, el autor y la imagen de la portada. Debes hacer clic en el libro para ver detalles adicionales.
{ title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>", year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution. }
En el esquema actual, para mostrar la información de la página principal del sitio web, se debe consultar toda la información del libro. Para reducir el tamaño del documento y agilizar las consultas, puede dividir el documento grande en dos colecciones más pequeñas.
Ejemplo
En el siguiente ejemplo, la información del libro se divide en dos colecciones: mainBookInfo y additionalBookDetails.
La colección
mainBookInfocontiene la información que se muestra en la página principal del sitio web.La colección
additionalBookDetailscontiene detalles adicionales que se revelan después de que un usuario hace clic en el libro.
La colección mainBookInfo:
db.mainBookInfo.insertOne( { _id: 1234, title: "Tale of Two Cities", author: "Charles Dickens", genre: "Historical Fiction", cover_image: "<url>" } )
La colección additionalBookDetails:
db.additionalBookDetails.insertOne( { title: "Tale of Two Cities", bookId: 1234, year: 1859, pages: 448, price: 15.99, description: "A historical novel set during the French Revolution." } )
Las dos colecciones están vinculadas por el campo _id de la colección mainBookInfo y el campo bookId de la colección additionalBookDetails. En la página de inicio, solo se utiliza la colección mainBookInfo para proporcionar la información necesaria. Cuando un usuario selecciona un libro para obtener más información, el sitio web consulta la colección additionalBookDetails utilizando el campo _id para encontrar la coincidencia con el campo bookId.
Al dividir la información en dos colecciones, se asegura de que sus documentos no crezcan demasiado ni excedan la asignación de RAM.
Unir colecciones con $lookup
Para unir los datos de la colección mainBookInfo y la colección additionalBookDetails, la aplicación debe realizar una operación de $lookup.
La siguiente operación de agregación une las colecciones mainBookInfo y additionalBookDetails del ejemplo anterior.
db.mainBookInfo.aggregate( [ { $lookup: { from: "additionalBookDetails", localField: "_id", foreignField: "bookId", as: "details" } }, { $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$details", 0 ] }, "$$ROOT" ] } } }, { $project: { details: 0 } } ] )
La operación devuelve lo siguiente:
[ { _id: ObjectId('666b1235eda086b5e22dbcf1'), title: 'Tale of Two Cities', author: 'Charles Dickens', genre: 'Historical Fiction', cover_image: '<url>', bookId: 1234, year: 1859, pages: 448, price: 15.99, description: 'A historical novel set during the French Revolution.' } ]
En este ejemplo, la operación $lookup une la colección mainBookInfo con la colección additionalBookDetails utilizando los campos _id y bookId. Las operaciones de $mergeObjects y $replaceRoot fusionan los documentos unidos de las colecciones mainBookInfo y additionalBookDetails.