La paginación es una parte crítica de cualquier operación de base de datos cuando se trata de grandes conjuntos de datos. Le permite dividir los datos en fragmentos manejables, lo que facilita su navegación, procesamiento y visualización. MongoDB proporciona dos métodos de paginación comunes: basado en desplazamiento y basado en cursor. Si bien ambos métodos tienen el mismo propósito, difieren significativamente en rendimiento y usabilidad, especialmente a medida que crece el conjunto de datos.
Profundicemos en los dos enfoques y veamos por qué la paginación basada en cursor a menudo supera a la paginación basada en desplazamiento.
La paginación basada en desplazamiento es sencilla. Recupera una cantidad específica de registros a partir de un desplazamiento determinado. Por ejemplo, la primera página puede recuperar los registros del 0 al 9, la segunda página recupera los registros del 10 al 19, y así sucesivamente.
Sin embargo, este método tiene un inconveniente importante: a medida que pasa a páginas superiores, la consulta se vuelve más lenta. Esto se debe a que la base de datos necesita omitir los registros de las páginas anteriores, lo que implica escanearlos.
Aquí está el código para la paginación basada en desplazamiento:
async function offset_based_pagination(params) { const { page = 5, limit = 100 } = params; const skip = (page - 1) * limit; const results = await collection.find({}).skip(skip).limit(limit).toArray(); console.log(`Offset-based pagination (Page ${page}):`, results.length, "page", page, "skip", skip, "limit", limit); }
La paginación basada en cursores, también conocida como paginación de conjunto de claves, se basa en un identificador único (por ejemplo, un ID o una marca de tiempo) para paginar los registros. En lugar de omitir una cierta cantidad de registros, utiliza el último registro recuperado como punto de referencia para buscar el siguiente conjunto.
Este enfoque es más eficiente porque evita la necesidad de escanear los registros antes de la página actual. Como resultado, el tiempo de consulta permanece constante, independientemente de qué tan profundo sea el conjunto de datos.
Aquí está el código para la paginación basada en cursor:
async function cursor_based_pagination(params) { const { lastDocumentId, limit = 100 } = params; const query = lastDocumentId ? { documentId: { $gt: lastDocumentId } } : {}; const results = await collection .find(query) .sort({ documentId: 1 }) .limit(limit) .toArray(); console.log("Cursor-based pagination:", results.length); }
En este ejemplo, lastDocumentId es el ID del último documento de la página anterior. Al consultar la página siguiente, la base de datos recupera documentos con un ID mayor que este valor, lo que garantiza una transición perfecta al siguiente conjunto de registros.
Veamos cómo funcionan estos dos métodos con un conjunto de datos grande.
async function testMongoDB() { console.time("MongoDB Insert Time:"); await insertMongoDBRecords(); console.timeEnd("MongoDB Insert Time:"); // Create an index on the documentId field await collection.createIndex({ documentId: 1 }); console.log("Index created on documentId field"); console.time("Offset-based pagination Time:"); await offset_based_pagination({ page: 2, limit: 250000 }); console.timeEnd("Offset-based pagination Time:"); console.time("Cursor-based pagination Time:"); await cursor_based_pagination({ lastDocumentId: 170000, limit: 250000 }); console.timeEnd("Cursor-based pagination Time:"); await client.close(); }
En la prueba de rendimiento, notarás que la paginación basada en desplazamiento tarda más a medida que el número de página aumenta, mientras que el cursor La paginación basada en sigue siendo consistente, lo que la convierte en la mejor opción para conjuntos de datos grandes. Este ejemplo también demuestra el poder de la indexación. ¡Intenta eliminar el índice y luego mira también el resultado!
Sin un índice, MongoDB necesitaría realizar un escaneo de la colección, lo que significa que tiene que mirar cada documento de la colección para encontrar los datos relevantes. Esto es ineficiente, especialmente cuando su conjunto de datos crece. Los índices permiten a MongoDB encontrar de manera eficiente los documentos que coincidan con las condiciones de su consulta, lo que acelera significativamente el rendimiento de la consulta.
En el contexto de la paginación basada en cursor, el índice garantiza que la recuperación del siguiente conjunto de documentos (basado en documentId) sea rápida y no degrade el rendimiento a medida que se agregan más documentos a la colección.
Si bien la paginación basada en desplazamiento es fácil de implementar, puede volverse ineficiente con grandes conjuntos de datos debido a la necesidad de escanear registros. La paginación basada en cursor, por otro lado, proporciona una solución más escalable, manteniendo el rendimiento constante independientemente del tamaño del conjunto de datos. Si trabaja con colecciones grandes en MongoDB, vale la pena considerar la paginación basada en cursor para una experiencia más fluida y rápida.
const { MongoClient } = require("mongodb"); const uri = "mongodb://localhost:27017"; const client = new MongoClient(uri); client.connect(); const db = client.db("testdb"); const collection = db.collection("testCollection"); async function insertMongoDBRecords() { try { let bulkOps = []; for (let i = 0; i 0) { await collection.bulkWrite(bulkOps); console.log("? Inserted records till now -> ", bulkOps.length); } console.log("MongoDB Insertion Completed"); } catch (err) { console.error("Error in inserting records", err); } } async function offset_based_pagination(params) { const { page = 5, limit = 100 } = params; const skip = (page - 1) * limit; const results = await collection.find({}).skip(skip).limit(limit).toArray(); console.log(`Offset-based pagination (Page ${page}):`, results.length, "page", page, "skip", skip, "limit", limit); } async function cursor_based_pagination(params) { const { lastDocumentId, limit = 100 } = params; const query = lastDocumentId ? { documentId: { $gt: lastDocumentId } } : {}; const results = await collection .find(query) .sort({ documentId: 1 }) .limit(limit) .toArray(); console.log("Cursor-based pagination:", results.length); } async function testMongoDB() { console.time("MongoDB Insert Time:"); await insertMongoDBRecords(); console.timeEnd("MongoDB Insert Time:"); // Create an index on the documentId field await collection.createIndex({ documentId: 1 }); console.log("Index created on documentId field"); console.time("Offset-based pagination Time:"); await offset_based_pagination({ page: 2, limit: 250000 }); console.timeEnd("Offset-based pagination Time:"); console.time("Cursor-based pagination Time:"); await cursor_based_pagination({ lastDocumentId: 170000, limit: 250000 }); console.timeEnd("Cursor-based pagination Time:"); await client.close(); } testMongoDB();
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3