对于复杂的mongodb调用,Node.js页面请求速度慢,如何加快速度?

时间:2018-04-10 14:48:12

标签: node.js mongodb

我正在加载"存档"页面,包括搜索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')
  })

})

1 个答案:

答案 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

谢谢