我试图通过下面的代码在mongodb中创建一个简单的分页。
collection.find().skip(n).limit(n);
Run Code Online (Sandbox Code Playgroud)
但是,如果我们发现使用java术语首先查找会返回所有记录(考虑到我有200万条记录),那么看起来是否会出现性能问题,然后将其传递给skip方法,然后将其传递给limit方法。这意味着每次该查询将获取所有数据库记录或mongodb驱动程序的工作方式不同时,我错过了什么?
在谈论MongoDB中的分页时,很容易编写以下代码:
collection.find().skip(pageSize*(pageNum-1)).limit(pageSize);
Run Code Online (Sandbox Code Playgroud)
上面是MongoDB支持的本机解决方案,但是如果集合中包含大量文档,则这样做效率不高。假设您有100M个文档,并且想要从中间偏移量(50Mth)中获取数据。MongoDB必须构建完整的数据集,并从头开始到指定的偏移量,这将导致性能低下。随着偏移量的增加,性能会不断下降。
根本原因是该skip()命令效率不高,无法从索引中获得很大收益。
下面是提高大数据分页性能的另一种解决方案:
分页的典型使用场景是有一个表或列表来显示指定页面的数据,还有一个“上一页”和“下一页”按钮来加载上一页或下一页的数据。
如果您获得了'_id'当前页面中最后一个文档的,则可以使用find()代替skip()。使用_id> currentPage_LastDocument._id作为查找下一页数据的条件之一。这是伪代码:
//Page 1
collection.find().limit(pageSize);
//Get the _id of the last document in this page
last_id = ...
//Page 2
users = collection.find({'_id': {$gt: last_id}}).limit(pageSize);
//Update the last id with the _id of the last document in this page
last_id = ...
Run Code Online (Sandbox Code Playgroud)
这样可以避免MongoDB在使用时遍历大数据skip()。