如何在Mongodb中实现分页?

时间:2011-12-05 09:50:02

标签: mongodb

我需要对一组文章进行分页(按日期排序 - 没有别的)。在Mongodb中做这样的事情的标准方法是什么?

由于性能问题,我不打算使用skip()方法。我也不打算使用$ push方法。我见过的最接近的方法是范围查询方法。但是如果删除了任何已排序的项目,它似乎会失败。

2 个答案:

答案 0 :(得分:9)

范围排序应该适合您。第一个请求将按日期排序前10个项目:

db.articles.find({}).sort( { date : -1 } ).limit(10);

在此之后,您将需要存储最后一个项目的某个日期,并在下一个分页请求中使用id:

db.articles.find({"date": {$lt: storedDateOfLastItem}}).sort( { date : -1 } ).limit(10);

所以,我想它应该适合你。要估算您需要使用的总页数count

  

但是如果删除了任何已排序的项目,它似乎会失败。

如果您要删除第1页中的文章,那么肯定会因为存储的上次日期而中断页面#2。为避免这种情况,您可以估算当前保存日期之前的项目数

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort( { date : -1 } ).count()

如果这个计数被改变了(假设有2个被删除)。您需要更新storedDateOfLastItem

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort( { date : -1 } ).take(2)

再次从上述请求的最后一项获取storedDateOfLastItem并继续进行分页。

但是我的意见只是保持这种分页,因为它没有额外的逻辑,因为我认为删除文章是罕见的操作。

来自mongodb文档:

  

分页成本不幸的是,跳过可能(非常)昂贵且需要   服务器从集合的开头或索引走到get   到它可以开始返回页面之前的偏移/跳过位置   数据(限制)。随着页码增加,跳过将变慢   更多的cpu密集型,可能是IO绑定的,具有更大的集合。

     

基于范围的分页提供了更好的索引使用但不允许   您可以轻松跳转到特定页面。

答案 1 :(得分:0)

如果您可以对索引进行排序,则可以使用“$ min”和“$ max”查询修饰符或范围查询来实现高效分页。确保您的索引在末尾包含唯一属性(例如“_id”)。

如果无法对索引进行排序,则可以预处理整个结果集并按顺序保留“_id”值列表。然后,您可以使用“$ in”查询运算符获取该列表的范围并查找结果页面。