La pagination basée sur le curseur peut être implémentée en utilisant n'importe quel champ de la collection qui est Unique, Commandable et Immuable .
_id
satisfaire tous les Uniques, Ordonnables et Immuables les conditions. Sur la base de ce champ, nous pouvons trier et renvoyer le résultat de la page avec _id
du dernier document en tant que curseur pour une demande ultérieure.
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 })
lorsque l'utilisateur veut obtenir la deuxième page, il passe le curseur (comme ci-dessous) sur l'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 nous voulons renvoyer les résultats dans un ordre différent, comme la date de l'élément, nous ajouterons sort=launchDate
à la chaîne de requête.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 })
Pour une demande de page ultérieurecurl 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 nous lancions un tas d'articles le même jour et à la même heure ? Maintenant notre launchDate
le champ n'est plus unique et ne satisfait pas Unique, Ordonnable et Immuable . condition. Nous ne pouvons pas l'utiliser comme champ de curseur. Mais nous pourrions utiliser deux champs pour générer le curseur. Puisque nous savons que le _id
champ dans MongoDB satisfait toujours les trois conditions ci-dessus, nous savons que si nous l'utilisons avec notre launchDate
champ, la combinaison des deux champs satisferait aux exigences et pourrait être utilisée ensemble comme champ de curseur.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 });
Pour une demande de page ultérieurecurl 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 });
Référence :https://engineering.mixmax.com/ blog/api-paging-built-the-right-way/