カーソルベースのページネーションは、コレクション内の一意、順序付け可能、不変の任意のフィールドを使用して実装できます。 。
_id
すべての一意、注文可能、不変を満たす 条件。このフィールドに基づいて、_id
を使用してページ結果を並べ替えて返すことができます 後続の要求のcusrorとして最後のドキュメントの。
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 })
ユーザーが2番目のページを取得したい場合は、次の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
フィールドは一意ではなくなり、一意、順序付け可能、不変を満たしていません 。調子。カーソルフィールドとして使用することはできません。ただし、2つのフィールドを使用してカーソルを生成することもできます。_id
がわかっているため、 MongoDBのフィールドは、常に上記の3つの条件を満たす場合、launchDate
と一緒に使用するとわかります。 フィールドの場合、2つのフィールドの組み合わせは要件を満たし、カーソルフィールドとして一緒に使用できます。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 });
参照: https://engineering.mixmax.com/ blog / api-paging-built-the-right-way /