MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie implementiert man Twitter- und Facebook-API-ähnliche Cursor-basierte Paginierung in Mongodb in nodejs mit dem offiziellen Mongodb-Client?

Cursorbasierte Paginierung kann mit jedem Feld in der Sammlung implementiert werden, das eindeutig, bestellbar und unveränderlich ist .

_id erfüllen alle Einzigartig, Bestellbar und Unveränderlich Bedingungen. Basierend auf diesem Feld können wir das Seitenergebnis mit _id sortieren und zurückgeben des letzten Dokuments als Cusror für spätere Anfragen.

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 })

Wenn der Benutzer die zweite Seite abrufen möchte, übergibt er den Cursor (als nächstes) an der 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 })

Wenn wir Ergebnisse in einer anderen Reihenfolge zurückgeben möchten, z. B. das Datum des Artikels, fügen wir sort=launchDate hinzu zum Querystring.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 nachfolgende Seitenanforderungen
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 });

Wenn wir eine Reihe von Artikeln am selben Tag und zur selben Uhrzeit auf den Markt bringen würden? Jetzt unser launchDate -Feld ist nicht mehr eindeutig und erfüllt nicht mehr Eindeutig, Bestellbar und Unveränderlich . Bedingung. Wir können es nicht als Cursorfeld verwenden. Aber wir könnten zwei Felder verwenden, um den Cursor zu generieren. Da wir wissen, dass die _id -Feld in MongoDB immer die oben genannten drei Bedingungen erfüllt, wissen wir das, wenn wir es zusammen mit unserem launchDate verwenden -Feld, würde die Kombination der beiden Felder die Anforderungen erfüllen und könnte zusammen als Cursorfeld verwendet werden.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 nachfolgende Seitenanforderungen
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 });

Referenz:https://engineering.mixmax.com/ blog/api-paging-richtig-gebaut/