我正在加载"存档"页面,包括搜索mongodb集合并在页面上显示许多文档。但是,执行此操作时,服务器调用需要一段时间。有什么建议让它更快?我认为缓慢来自这条线:
Publication.find().limit(perPage).skip(perPage * page).sort('-date').exec(function (err, _publications) {
整页请求:
app.get('/archive', function (req, res) {
function timeConverter(UNIX_timestamp){
var a = new Date(UNIX_timestamp);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var time = date + ' ' + month + ' ' + year;
return time;
}
var perPage = 6
pageParam = req.query['page']
if (pageParam == null) {
pageParam = 0
}
var page = Math.max(0, pageParam)
// find all publications
Publication.find().limit(perPage).skip(perPage * page).sort('-date').exec(function (err, _publications) {
if (err) return console.error(err)
for (id in _publications) { // convert date to text
_publications[id].date = timeConverter( Number(_publications[id].date) )
}
Publication.find().limit(perPage).skip(perPage * (page + 1) ).count({},function(err, count) { // check if it's last page
if (err) return console.error(err)
if (count == 0) {
nextPage = false
} else {
nextPage = page + 1
}
res.render(__dirname + '/../source/views/archive', {
publications: _publications,
nextPage: nextPage,
prevPage: page - 1
})
})
console.log('serving archive')
})
})
答案 0 :(得分:1)
执行.limit(perPage).skip(perPage * page)
会影响您的响应时间。这被认为是最佳方法,因为mongo将首先扫描指定集合中的所有先前文档,然后skip
。
更好的解决方案是使_id
的所有文档都大于第一个响应中发送的文档。像
Publication.find({'_id': {'$gt': req.params.last_id}}, {}, { limit: perPage })
此处last_id
是最后一个文档的id
,此查询将返回该ID之后的所有(或指定数量)文档。
此外,mongodb在其生成的id上应用索引,使用它进行搜索总是更快。
您的方法缓慢的主要原因是使用skip
cursor.skip()
方法通常很昂贵,因为它要求服务器从集合或索引的开头走,以在开始返回结果之前获取偏移或跳过位置。随着偏移量(例如上面的pageNumber)的增加,cursor.skip()将变得更慢并且CPU密集度更高。对于较大的集合,cursor.skip()可能会成为IO绑定
了解更多here
谢谢