我需要对一组文章进行分页(按日期排序 - 没有别的)。在Mongodb中做这样的事情的标准方法是什么?
由于性能问题,我不打算使用skip()方法。我也不打算使用$ push方法。我见过的最接近的方法是范围查询方法。但是如果删除了任何已排序的项目,它似乎会失败。
答案 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”查询运算符获取该列表的范围并查找结果页面。