Phân trang dựa trên con trỏ có thể được triển khai bằng cách sử dụng bất kỳ trường nào trong bộ sưu tập Duy nhất, Có thể xác định và Bất biến .
_id
đáp ứng tất cả Duy nhất, Có thể xác định và Bất biến các điều kiện. Dựa trên trường này, chúng tôi có thể sắp xếp và trả về kết quả trang bằng _id
của tài liệu cuối cùng với tư cách là người viết thư cho yêu cầu tiếp theo.
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 })
khi người dùng muốn truy cập trang thứ hai, họ chuyển con trỏ (như tiếp theo) vào 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 })
Nếu chúng ta muốn trả về kết quả theo một thứ tự khác, chẳng hạn như ngày của mặt hàng, thì chúng ta sẽ thêm sort=launchDate
vào chuỗi truy vấn. 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 })
Đối với yêu cầu trang tiếp theo
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 });
Nếu chúng tôi tung ra một loạt các mặt hàng vào cùng một ngày và giờ? Bây giờ launchDate
của chúng tôi trường không còn duy nhất và không đáp ứng Duy nhất, Có thể xác định và Bất biến . tình trạng. Chúng tôi không thể sử dụng nó làm trường con trỏ. Nhưng chúng ta có thể sử dụng hai trường để tạo con trỏ Vì chúng ta biết rằng _id
trường trong MongoDB luôn thỏa mãn ba điều kiện trên, chúng tôi biết rằng nếu chúng tôi sử dụng nó cùng với launchDate
của chúng tôi trường, sự kết hợp của hai trường sẽ đáp ứng các yêu cầu và có thể được sử dụng cùng nhau làm trường con trỏ. 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 });
Đối với yêu cầu trang tiếp theo
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 /