MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Come implementare l'API di Twitter e Facebook come l'impaginazione basata sul cursore in mongodb in nodejs utilizzando il client mongodb ufficiale?

L'impaginazione basata su cursore può essere implementata utilizzando qualsiasi campo della raccolta che sia Unico, Ordinabile e immutabile .

_id soddisfare tutti gli Unici, Ordinabili e Immutabili condizioni. Sulla base di questo campo possiamo ordinare e restituire il risultato della pagina con _id dell'ultimo documento come cusro per la successiva richiesta.

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

quando l'utente vuole ottenere la seconda pagina, passa il cursore (come successivo) sull'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 })

Se vogliamo restituire i risultati in un ordine diverso, come la data dell'articolo, aggiungeremo sort=launchDate alla 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 })

Per la richiesta di pagina successiva
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 });

Se lanciassimo un mucchio di articoli nello stesso giorno e ora? Ora il nostro launchDate il campo non è più unico e non soddisfa Unico, Ordinabile e Immutabile . condizione. Non possiamo usarlo come campo cursore. Ma potremmo usare due campi per generare il cursore. Dal momento che sappiamo che il _id campo in MongoDB soddisfa sempre le tre condizioni precedenti, sappiamo che se lo usiamo insieme al nostro launchDate campo, la combinazione dei due campi soddisferebbe i requisiti e potrebbe essere utilizzata insieme come campo cursore.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 });

Per la richiesta di pagina successiva
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 });

Riferimento:https://engineering.mixmax.com/ blog/api-paging-costruito-nel-modo-giusto/