好多人说mongodb分页不要用skip,但是网上搜了好久也没搜到解决办法 以前学过java,他们基于Mysql数据库的分页好像是取得符合查询的全部数据放在list里面 然后fetch带两个参数去取数据,实现分页 我就想着能不能也使用这个办法,然后自己写了个简单的实现类 代码在http://blog.csdn.net/chengscau/article/details/40188087 求大家告诉我好点的解决方案,有代码看是最好了~
不是一次性读取所有的数据,应该是:
- 确定分页依据的记录域(field),建立索引;
- 每次执行一个区间查询(range query),对这次查询结果分页。注意:要根据上一次区间查询的结果,修改本次区间查询的条件。
参考代码:MongoDB数据库,使用区间查询分页
MongoDB cursor.skip文档也是推荐使用区间查询,实现高效地分页。
还可以参考这个演示文稿(可能需要科学上网):应该这么分页,内容是使用PostgresSQL数据库,利用区间查询而不是SQL OFFSET实现分页功能,比较了两种方法的查询性能。
有两种处理方法:
-
不用页面底部显示
<< < 1 2 3 4 5 > >>
的方式,而是采用twitter或者微博那种无限下拉获取新记录的方式。这实际上相当于每次只能读取下一页的内容,也就不存在用户跳到特定页面的问题; -
仍然采用页面底部显示
<< < 1 2 3 4 5 > >>
的方式,是不是可以一次读取5页的内容?在这5页范围内的跳转,就不用再读数据库。如果要调到第6页,那就再来一次区间查询。
目前我个人所知的分页方式有两种: 1)skip + limit 的方式 2)$gt($get) + $lt($lte) + limit 的方式
第一种方式更适合pc网页的数字分页 第二种方式更适合mobile网页的上一页和下一页的分页
关于性能问题, 能确定的是:尽量配合一个能大幅度缩小mongodb查询范围的查询条件 举个例子: 如果 topic 列表按照最后更新时间字段 last_update_date 倒序排列, 除了limit和确保击中索引 { last_update_date:-1 } 之外, 实际查询条件可以加入一天的查询: { last_update_date:{$gte:new Date(‘2015-01-01 00:00:00’), $lte:new Date(‘2015-01-02 23:59:59’)}}
这种方式在能有效控制mongodb查询数据的时间成本。