sql >> Database >  >> NoSQL >> MongoDB

Hoe twitter en facebook api-achtige cursorgebaseerde paginering in mongodb in nodejs te implementeren met behulp van de officiële mongodb-client?

Op cursor gebaseerde paginering kan worden geïmplementeerd met elk veld in de verzameling dat Uniek, Bestelbaar en Onveranderlijk is .

_id voldoen aan alle uniek, bestelbaar en onveranderlijk conditie. Op basis van dit veld kunnen we paginaresultaten sorteren en retourneren met _id van het laatste document als de cusror voor een volgend verzoek.

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

wanneer de gebruiker de tweede pagina wil krijgen, passeren ze de cursor (zoals hierna) op de 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 })

Als we resultaten in een andere volgorde willen retourneren, zoals de datum van het item, dan voegen we sort=launchDate toe naar de 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 })

Voor volgende paginaverzoek
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 });

Als we een heleboel items op dezelfde dag en hetzelfde tijdstip lanceren? Nu onze launchDate veld is niet langer uniek en voldoet niet aan Unique, Orderable and Immutable . voorwaarde. We kunnen het niet als cursorveld gebruiken. Maar we zouden twee velden kunnen gebruiken om de cursor te genereren. Omdat we weten dat de _id veld in MongoDB altijd voldoet aan de bovenstaande drie voorwaarden, weten we dat als we het naast onze launchDate gebruiken veld, zou de combinatie van de twee velden aan de vereisten voldoen en samen als cursorveld kunnen worden gebruikt.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 });

Voor volgende paginaverzoek
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 });

Referentie:https://engineering.mixmax.com/ blog/api-paging-built-the-right-way/




  1. Push to Laravel wachtrij van buiten Laravel (NodeJS)

  2. ScaleGrid Hosting voor Redis™ op uw eigen AWS-account

  3. Kan sharded mongoDB niet upgraden of de balancer stoppen

  4. Java-resultaat oplossen 137