MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como implementar a API do twitter e do facebook como paginação baseada em cursor no mongodb no nodejs usando o cliente oficial do mongodb?


A paginação baseada em cursor pode ser implementada usando qualquer campo na coleção que seja Único, Ordenável e Imutável .

_id satisfazer todos os Únicos, Ordenáveis ​​e Imutáveis condições. Com base neste campo, podemos classificar e retornar o resultado da página com _id do último documento como cursor para solicitação posterior.

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 o usuário deseja obter a segunda página, ele passa o cursor (como a seguir) na 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 quisermos retornar os resultados em uma ordem diferente, como a data do item, adicionaremos sort=launchDate para a 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 })

Para solicitação de página subsequente
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 lançássemos vários itens no mesmo dia e horário? Agora nosso launchDate campo não é mais exclusivo e não atende a Único, Ordenável e Imutável . doença. Não podemos usá-lo como um campo de cursor. Mas podemos usar dois campos para gerar o cursor. Como sabemos que o _id campo no MongoDB sempre satisfaz as três condições acima, sabemos que se o usarmos junto com nosso launchDate campo, a combinação dos dois campos atenderia aos requisitos e poderia ser usada em conjunto como um campo de cursor.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 });

Para solicitação de página subsequente
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 });

Referência:https://engineering.mixmax.com/ blog/api-pageing-built-the-right-way/