sql >> Base de Datos >  >> NoSQL >> MongoDB

Paginación rápida con MongoDB

Paginar sus datos es una de las operaciones más comunes con MongoDB. Un escenario típico es la necesidad de mostrar sus resultados en fragmentos en su interfaz de usuario. Si está procesando sus datos por lotes, también es importante que su estrategia de paginación sea correcta para que su procesamiento de datos pueda escalar.

Veamos un ejemplo para ver las diferentes formas de pasar páginas por los datos en MongoDB. En este ejemplo, tenemos una base de datos de CRM de datos de usuario que necesitamos hojear y mostrar 10 usuarios a la vez. En efecto, nuestro tamaño de página es 10. Esta es la estructura de nuestro documento de usuario:

{
    _id,
    name,
    company,
    state
}

Enfoque 1:usar skip() y limit()

MongoDB admite de forma nativa la operación de paginación mediante los comandos skip() y limit(). La directiva skip(n) le dice a MongoDB que debe omitir 'n' resultados, y la directiva limit(n) le indica a MongoDB que debe limitar la longitud del resultado a 'n' resultados. Por lo general, usará las directivas skip() y limit() con el cursor, pero para ilustrar el escenario, proporcionamos comandos de consola que lograrían los mismos resultados. Además, por brevedad del código, también se excluye el código de verificación de límites:

//Page 1
db.users.find().limit (10)
//Page 2
db.users.find().skip(10).limit(10)
//Page 3
db.users.find().skip(20).limit(10)
........

Entiendes la idea. En general, para recuperar la página 'n', el código se ve así:

db.users.find().skip(pagesize*(n-1)).limit(pagesize)

Sin embargo, a medida que aumenta el tamaño de sus datos, este enfoque tiene serios problemas de rendimiento. La razón es que cada vez que se ejecuta la consulta, se genera el conjunto de resultados completo, luego el servidor tiene que caminar desde el comienzo de la colección hasta el desplazamiento especificado. A medida que aumenta su compensación, este proceso se vuelve más y más lento. Además, este proceso no hace un uso eficiente de los índices. Por lo general, el enfoque 'skip()' y 'limit()' es útil cuando tiene conjuntos de datos pequeños, y si está trabajando con conjuntos de datos grandes, querrá considerar otros enfoques.

Enfoque 2:Uso de find() y limit()

La razón por la que el enfoque anterior no escala muy bien es el comando skip(), y el objetivo de esta sección es implementar la paginación sin usar el comando 'skip()'. Para esto, aprovecharemos el orden natural en los datos almacenados, como una marca de tiempo o una identificación almacenada en el documento. En este ejemplo, vamos a utilizar el '_id' almacenado en cada documento. '_id' es una estructura MongoDB ObjectID que es una estructura de 12 bytes que contiene una marca de tiempo, mecanizado, ID de proceso, contador, etc. La idea general es la siguiente:

1. Recuperar el _id del último documento en la página actual
2. Recupere documentos mayores que este “_id” en la página siguiente

//Page 1
db.users.find().limit(pageSize);
//Find the id of the last document in this page
last_id = ...

//Page 2
users = db.users.find({'_id'> last_id}). limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

Este enfoque aprovecha el orden inherente que existe en el campo "_id". Además, dado que el campo "_id" está indexado de forma predeterminada, el rendimiento de la operación de búsqueda es muy bueno. Si el campo que está utilizando no está indexado, su rendimiento se verá afectado, por lo que es importante asegurarse de que ese campo esté indexado.

Además, si desea que sus datos se clasifiquen en un orden particular para su paginación, también puede usar la cláusula sort() con la técnica anterior. Es importante asegurarse de que el proceso de clasificación aproveche un índice para obtener el mejor rendimiento. Puede usar el sufijo .explain() en su consulta para determinar esto:

users = db.users.find({'_id'> last_id}). sort(..).limit(10);
//Update the last id with the id of the last document in this page
last_id = ...

Como siempre, si tiene alguna pregunta o comentario, no dude en comunicarse con nosotros en [email protected].