Markörbaserad paginering kan implementeras med vilket fält som helst i samlingen som är Unik, Beställningsbar och oföränderlig .
_id
tillfredsställa alla Unika, beställningsbara och oföränderliga betingelser. Baserat på detta fält kan vi sortera och returnera sidresultat med _id
av det senaste dokumentet som kurator för efterföljande begäran.
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 })
när användaren vill få den andra sidan skickar de markören (som nästa) på URL:en: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 })
Om vi vill returnera resultat i en annan ordning, t.ex. datumet för objektet, lägger vi till sort=launchDate
till frågesträngen.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 })
För efterföljande sidförfrågancurl 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 });
Om vi lanserade ett gäng artiklar på samma dag och tid? Nu vår launchDate
fältet är inte längre unikt och uppfyller inte Unique, Orderable och Immutable . skick. Vi kan inte använda det som ett markörfält. Men vi kan använda två fält för att generera markören. Eftersom vi vet att _id
fältet i MongoDB alltid uppfyller ovanstående tre villkor, vi vet att om vi använder det tillsammans med vår launchDate
fältet skulle kombinationen av de två fälten uppfylla kraven och skulle kunna användas tillsammans som ett markörfält.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 });
För efterföljande sidförfrågancurl 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 });
Referens:https://engineering.mixmax.com/ blog/api-paging-built-the-right-way/