La paginación basada en cursor se puede implementar utilizando cualquier campo de la colección que sea único, ordenable e inmutable .
_id
satisfacer todos los Únicos, Ordenables e Inmutables condiciones. Según este campo, podemos ordenar y devolver el resultado de la página con _id
del último documento como el cusror para la solicitud posterior.
curl https://api.mixmax.com/items?limit=2
const items = db.items.find({}).sort({
_id: -1
}).limit(2);
const next = items[items.length - 1]._id
res.json({ items, next })
cuando el usuario quiere obtener la segunda página, pasa el cursor (como se muestra a continuación) en la URL:curl https://api.mixmax.com/items?limit=2&next=590e9abd4abbf1165862d342
const items = db.items.find({
_id: { $lt: req.query.next }
}).sort({
_id: -1
}).limit(2);
const next = items[items.length - 1]._id
res.json({ items, next })
Si queremos devolver los resultados en un orden diferente, como la fecha del elemento, agregaremos sort=launchDate
a la cadena de consulta.curl https://api.mixmax.com/items?limit=2&sort=launchDate
const items = db.items.find({}).sort({
launchDate: -1
}).limit(2);
const next = items[items.length - 1].launchDate;
res.json({ items, next })
Para la solicitud de página posteriorcurl https://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A44%3A54.036Z
const items = db.items.find({
launchDate: { $lt: req.query.next }
}).sort({
_id: -1
}).limit(2);
const next = items[items.length - 1].launchDate;
res.json({ items, next });
¿Si lanzamos un montón de artículos el mismo día y hora? Ahora nuestra launchDate
el campo ya no es único y no cumple con Unique, Orderable and Immutable . condición. No podemos usarlo como un campo de cursor. Pero podríamos usar dos campos para generar el cursor. Ya que sabemos que el _id
El campo en MongoDB siempre satisface las tres condiciones anteriores, sabemos que si lo usamos junto con nuestra launchDate
campo, la combinación de los dos campos cumpliría los requisitos y podrían usarse juntos como un campo de cursor.curl https://api.mixmax.com/items?limit=2&sort=launchDate
const items = db.items.find({}).sort({
launchDate: -1,
_id: -1 // secondary sort in case there are duplicate launchDate values
}).limit(2);
const lastItem = items[items.length - 1];
// The cursor is a concatenation of the two cursor fields, since both are needed to satisfy the requirements of being a cursor field
const next = `${lastItem.launchDate}_${lastItem._id}`;
res.json({ items, next });
Para solicitud de página posteriorcurl https://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A44%3A54.036Z_590e9abd4abbf1165862d342
const [nextLaunchDate, nextId] = req.query.next.split(‘_’);
const items = db.items.find({
$or: [{
launchDate: { $lt: nextLaunchDate }
}, {
// If the launchDate is an exact match, we need a tiebreaker, so we use the _id field from the cursor.
launchDate: nextLaunchDate,
_id: { $lt: nextId }
}]
}).sort({
_id: -1
}).limit(2);
const lastItem = items[items.length - 1];
// The cursor is a concatenation of the two cursor fields, since both are needed to satisfy the requirements of being a cursor field
const next = `${lastItem.launchDate}_${lastItem._id}`;
res.json({ items, next });
Referencia:https://engineering.mixmax.com/ blog/api-paging-construido-de-la-manera-correcta/