MongoDB的分页

据说在具有多个logging的MongoDB集合中使用skip()进行分页很慢并且不推荐。

可以使用远程分页(基于> _id比较)

db.items.find({_id: {$gt: ObjectId('4f4a3ba2751e88780b000000')}}); 

这对于显示prev是很好的。 &nextbutton – 但是当要显示实际的页码时,实现并不是很容易1 … 5 6 7 … 124 – 您需要预先计算每个页面从哪个“_id”开始。

所以我有两个问题:

1)我应该什么时候开始担心? 当skip()有明显减速的“logging太多”时? 1 000? 1 000 000?

2)什么是使用范围分页显示与实际页码的链接的最佳方法?

好问题!

“多less太多了?” – 当然,这取决于您的数据大小和性能要求。 当我跳过超过500-1000条logging时,我个人感到不舒服。

实际的答案取决于你的要求。 这是现代网站所做的(或者至less是其中的一些)。

首先,navbar看起来像这样:

 1 2 3 ... 457 

他们从总logging数和页面大小中获得最终页码。 让我们跳到第3页。这将涉及到从第一个logging跳过。 结果到达时,您知道第3页上的第一条logging的ID。

 1 2 3 4 5 ... 457 

让我们跳过一些并转到第5页。

 1 ... 3 4 5 6 7 ... 457 

你明白了。 在每一个点你看到第一个,最后一个和当前页面,还有两个页面从当前页面向前和向后。

查询

 var current_id; // id of first record on current page. // go to page current+N db.collection.find({_id: {$gte: current_id}}). skip(N * page_size). limit(page_size). sort({_id: 1}); // go to page current-N // note that due to the nature of skipping back, // this query will get you records in reverse order // (last records on the page being first in the resultset) // You should reverse them in the app. db.collection.find({_id: {$lt: current_id}}). skip((N-1)*page_size). limit(page_size). sort({_id: -1}); 

很难给出一个一般的答案,因为它很大程度上取决于您正在使用哪些查询(或多个查询)来构造正在显示的结果集。 如果只使用索引find结果并以索引顺序显示,那么即使大量跳过,db.dataset.find().limit().skip()也可以执行。 这可能是编码最简单的方法。 但即使在这种情况下,例如,如果您可以caching页码并将其绑定到索引值,则可以使第二个和第三个人更快地查看第71页。

在一个非常dynamic的数据集中,文档将被添加和删除,而其他人正在通过数据进行分页,这样的caching将变得过时,限制和跳过方法可能是唯一可靠的,以提供良好的结果。