版本号:Keystone v4
我有一个Mongo数据库>20k项。我想要的是一个分页器,允许用户一次快速滚动Mongo数据库25个元素。目前,这个特性已经实现,但是服务器需要40秒才能返回结果,因为它查询了整个(20k项)数据库。然而,只有25个元素显示在一个页面上,所以我觉得如果它只是获取25个结果,而不是20k,它应该更快。我该如何实现呢?我知道.limit()
函数,但是在使用它时,我似乎无法弄清楚keystone中的分页。
当前代码:
var q = Items.model.find();
q.exec(function(err, newss) {
console.log('There are %d', newss.length); // Prints out 20k number
...//skip
locals.cnts = newss;
// console.log(newss[0])
locals.pagerr = pager({
page: parseInt(req.query.page, 10) || 1,
perPage: 25,
total: newss.length
});
locals.itemsss = locals.cnts.slice(
locals.pagerr.first - 1,
locals.pagerr.last
);
next();
})
在当前的实现中,需要40秒才能返回分页结果。我该如何解决这个问题?
这里使用的model.find()
函数相当于Mongoosefind()
函数。由于调用时没有使用任何过滤器,因此下面的代码从数据库中检索所有25k项每次运行。这些数据被传输到运行function(err, newss) {...}
函数体的web服务器/节点进程。只有和是从集合中提取的25个项目。
相反,如果您希望像这样使用基于偏移量的分页,则应该使用query.limit()
和query.skip()
函数。如果您需要首先计算总项目,请使用query.count()
在单独的查询中执行此操作。
我还没有测试过这段代码(自从我使用Mongoose以来已经有一段时间了),但我认为你想要这样的东西:
// Warning! Untested example code
Items.model.find().count(function (err, count) {
console.log('There are %d', count);
locals.pager = pager({
page: parseInt(req.query.page, 10) || 1,
perPage: 25,
total: count
});
Items.model.find()
.skip(locals.pager.first)
.limit(25)
.exec(function(err, results) {
locals.results = results;
next();
});
});
在一个更一般的说明-如果你喜欢Keystone,想要使用Mongo,保持关注Keystone 6的更新。Keystone 6使用Prisma 2作为它的ORM层,他们最近发布了对Mongo的支持。一旦这个功能准备好了,我们也会在Keystone中支持它。