Node.js 如何使用官方的mongodb客户端在nodejs中的mongodb中实现twitter和facebook api,比如基于光标的分页?
我正在尝试实现在数据插入或删除时不应在不同页面中显示重复数据的功能 在此基础上给出了使用和分页数据的基本方法Node.js 如何使用官方的mongodb客户端在nodejs中的mongodb中实现twitter和facebook api,比如基于光标的分页?,node.js,mongodb,express,pagination,real-time,Node.js,Mongodb,Express,Pagination,Real Time,我正在尝试实现在数据插入或删除时不应在不同页面中显示重复数据的功能 在此基础上给出了使用和分页数据的基本方法 基于偏移量的方法有一个很大的缺陷:如果在调用API的过程中结果列表发生了变化,索引将发生移动,导致项目返回两次,或者跳过并从未返回 此问题在 基于时间的分页方法会稍好一些,因为不再跳过结果。如果查询第一个页面,然后删除一个新项目,则不会移动第二个页面中的结果,一切正常。但是,这种方法有一个主要缺陷:如果同时创建了多个项,该怎么办 基于偏移量和基于时间的方法并不完美。所以我需要 twi
基于偏移量的方法有一个很大的缺陷:如果在调用API的过程中结果列表发生了变化,索引将发生移动,导致项目返回两次,或者跳过并从未返回 此问题在
基于时间的分页方法会稍好一些,因为不再跳过结果。如果查询第一个页面,然后删除一个新项目,则不会移动第二个页面中的结果,一切正常。但是,这种方法有一个主要缺陷:如果同时创建了多个项,该怎么办 基于偏移量和基于时间的方法并不完美。所以我需要
twitter和facebook api的工作方式使用基于光标的方法,使用NodeJ和基于光标的分页,可以使用集合中唯一、可排序和不可变的任何字段来实现
\u id
满足所有唯一、有序和不可变的条件。基于此字段,我们可以对页面结果进行排序并返回最后一个文档的\u id
,作为后续请求的cusror
curlhttps://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 })
当用户想要获取第二个页面时,他们会在URL上传递光标(作为下一个):
curlhttps://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 })
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 });
如果我们希望以不同的顺序返回结果,例如项目的日期,那么我们将向querystring添加sort=launchDate
。
curlhttps://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 })
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 });
用于后续页面请求curlhttps://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A4%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 });
如果我们在同一天同一时间推出一系列产品?现在,我们的launchDate
字段不再是唯一的,并且不满足唯一、可排序和不可变的要求。条件我们不能将其用作光标字段。但是我们可以使用两个字段来生成游标。因为我们知道MongoDB中的\u id
字段始终满足上述三个条件,所以我们知道如果我们将它与launchDate
字段一起使用,这两个字段的组合将满足要求,并且可以一起用作游标字段。
curlhttps://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 })
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 });
用于后续页面请求curlhttps://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A4%3A54.036Z_590E9abd4abf115862d342
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 })
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 });
参考:基于光标的分页可以使用集合中唯一、可排序且不可变的任何字段来实现
\u id
满足所有唯一、有序和不可变的条件。基于此字段,我们可以对页面结果进行排序并返回最后一个文档的\u id
,作为后续请求的cusror
curlhttps://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 })
当用户想要获取第二个页面时,他们会在URL上传递光标(作为下一个):
curlhttps://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 })
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 });
如果我们希望以不同的顺序返回结果,例如项目的日期,那么我们将向querystring添加sort=launchDate
。
curlhttps://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 })
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 });
用于后续页面请求curlhttps://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A4%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 });
如果我们在同一天同一时间推出一系列产品?现在,我们的launchDate
字段不再是唯一的,并且不满足唯一、可排序和不可变的要求。条件我们不能将其用作光标字段。但是我们可以使用两个字段来生成游标。因为我们知道MongoDB中的\u id
字段始终满足上述三个条件,所以我们知道如果我们将它与launchDate
字段一起使用,这两个字段的组合将满足要求,并且可以一起用作游标字段。
curlhttps://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 })
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 });
用于后续页面请求curlhttps://api.mixmax.com/items?limit=2&sort=launchDate&next=2017-09-11T00%3A4%3A54.036Z_590E9abd4abf115862d342
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 })
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 });
参考:使用ObjectId进行分页。它是唯一且基于时间的。请使用ObjectId进行分页。它是独一无二的,以时间为基础的。