Пагинацията, базирана на курсора, може да бъде приложена с помощта на всяко поле в колекцията, което е Уникално, Подреждаемо и Неизменно .
_id
отговарят на всички Уникални, подлежащи на поръчка и неизменни условия. Въз основа на това поле можем да сортираме и да върнем резултат от страница с _id
на последния документ като потребител за последваща заявка.
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 })
когато потребителят иска да получи втората страница, той прекарва курсора (както следва) върху 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 })
Ако искаме да върнем резултати в различен ред, като например датата на елемента, тогава ще добавим sort=launchDate
към низа на заявката.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 })
За следваща заявка за страницаcurl 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 });
Ако стартираме куп артикули в един и същи ден и час? Сега нашият launchDate
полето вече не е уникално и не удовлетворява Уникално, подреждаемо и неизменно . състояние. Не можем да го използваме като поле за курсор. Но можем да използваме две полета, за да генерираме курсора. Тъй като знаем, че _id
поле в MongoDB винаги отговаря на горните три условия, ние знаем, че ако го използваме заедно с нашата launchDate
поле, комбинацията от двете полета ще удовлетвори изискванията и може да се използва заедно като поле за курсор.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 });
За следваща заявка за страницаcurl 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 });
Refefence:https://engineering.mixmax.com/ blog/api-paging-built-the-right-way/