Paginação é uma parte crítica de qualquer operação de banco de dados ao lidar com grandes conjuntos de dados. Ele permite dividir os dados em partes gerenciáveis, facilitando a navegação, o processamento e a exibição. O MongoDB fornece dois métodos de paginação comuns: baseado em deslocamento e baseado em cursor. Embora ambos os métodos tenham o mesmo propósito, eles diferem significativamente em desempenho e usabilidade, especialmente à medida que o conjunto de dados cresce.
Vamos mergulhar nas duas abordagens e ver por que a paginação baseada em cursor geralmente supera a paginação baseada em deslocamento.
A paginação baseada em deslocamento é simples. Ele recupera um número específico de registros a partir de um determinado deslocamento. Por exemplo, a primeira página pode recuperar os registros de 0 a 9, a segunda página recupera os registros de 10 a 19 e assim por diante.
No entanto, esse método tem uma desvantagem significativa: conforme você passa para páginas superiores, a consulta se torna mais lenta. Isso ocorre porque o banco de dados precisa pular os registros das páginas anteriores, o que envolve examiná-los.
Aqui está o código para paginação baseada em deslocamento:
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); }
A paginação baseada em cursor, também conhecida como paginação de conjunto de chaves, depende de um identificador exclusivo (por exemplo, um ID ou carimbo de data/hora) para paginar os registros. Em vez de pular um certo número de registros, ele usa o último registro recuperado como ponto de referência para buscar o próximo conjunto.
Essa abordagem é mais eficiente porque evita a necessidade de digitalizar os registros antes da página atual. Como resultado, o tempo de consulta permanece consistente, independentemente da profundidade do conjunto de dados.
Aqui está o código para paginação baseada em 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); }
Neste exemplo, lastDocumentId é o ID do último documento da página anterior. Ao consultar a próxima página, o banco de dados busca documentos com um ID maior que esse valor, garantindo uma transição perfeita para o próximo conjunto de registros.
Vamos ver o desempenho desses dois métodos com um grande conjunto de dados.
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(); }
No teste de desempenho, você notará que a paginação baseada em deslocamento demora mais à medida que o número da página aumenta, enquanto o cursor A paginação baseada em permanece consistente, tornando-a a melhor escolha para conjuntos de dados grandes. Este exemplo também demonstra o poder da indexação. Tente remover o índice e veja o resultado também!
Sem um índice, o MongoDB precisaria realizar uma varredura de coleção, o que significa que ele teria que examinar cada documento da coleção para encontrar os dados relevantes. Isto é ineficiente, especialmente quando o seu conjunto de dados cresce. Os índices permitem que o MongoDB encontre com eficiência os documentos que correspondem às condições da sua consulta, acelerando significativamente o desempenho da consulta.
No contexto da paginação baseada em cursor, o índice garante que a busca do próximo conjunto de documentos (com base em documentId) seja rápida e não prejudique o desempenho à medida que mais documentos são adicionados à coleção.
Embora a paginação baseada em deslocamento seja fácil de implementar, ela pode se tornar ineficiente com grandes conjuntos de dados devido à necessidade de digitalizar registros. A paginação baseada em cursor, por outro lado, fornece uma solução mais escalonável, mantendo o desempenho consistente independentemente do tamanho do conjunto de dados. Se você estiver trabalhando com grandes coleções no MongoDB, vale a pena considerar a paginação baseada em cursor para uma experiência mais suave e 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();
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3