在populate上使用sort和skip进行mongoose查询太慢了

时间:2017-12-30 17:15:21

标签: node.js mongodb mongoose

我正在使用来自前端的ajax请求从后端加载更多注释到使用NodeJS和mongoose的后端。我不会厌烦你的前端代码和路由代码,但这里是查询代码:

Post.findById(req.params.postId).populate({
    path: type, //type will either contain "comments" or "answers"
    populate: {
        path: 'author',
        model: 'User'
    },
    options: {
        sort: sortBy, //sortyBy contains either "-date" or "-votes"
        skip: parseInt(req.params.numberLoaded), //how many are already shown
        limit: 25 //i only load this many new comments at a time.
    }
}).exec(function(err, foundPost){
    console.log("query executed"); //code takes too long to get to this line
    if (err){
        res.send("database error, please try again later");
    } else {
        res.send(foundPost[type]);
    }
});

正如标题中提到的,一切正常,我的问题只是这太慢了,请求大约需要1.5-2.5秒。当然,mongoose有一种方法可以减少负载。我探索了mongoose docs和stackoverflow,但没有找到任何有用的东西。

1 个答案:

答案 0 :(得分:3)

使用mongodb的skip-and-limit方法本质上很慢,因为它通常需要检索所有文档,然后对它们进行排序,然后返回所需的结果段。

要使其更快,您需要做的是在集合中定义索引 根据MongoDB的官方文件:

  

索引支持在MongoDB中高效执行查询。如果没有索引,MongoDB必须执行集合扫描,即扫描集合中的每个文档,以选择与查询语句匹配的文档。如果查询存在适当的索引,MongoDB可以使用索引来限制它必须检查的文档数量    - https://docs.mongodb.com/manual/indexes/

使用索引可能会导致收集量增加,但它们可以大大提高效率。

索引通常在查询中经常使用的字段上定义。在这种情况下,您可能希望在date和/或vote字段上定义索引。

阅读mongoose文档,了解如何在模式中定义索引: http://mongoosejs.com/docs/guide.html#indexes