如何在MongoDB中使用范围查询进行分页?

时间:2011-04-02 19:17:08

标签: mongodb pagination

我可能会遗漏一些东西,因为我还在学习ins和 MongoDB的出局,但我需要帮助分页集合。

我有一个包含名单的集合。

牛肉底部 鸡胸肉6oz
鸡胸肉8oz
鸡胸肉8oz
鸡胸肉8oz
鸡胸肉随机
鸡腿
鸡里脊肉
鸡大腿
洁净盐

我在“ProductName,_id”上创建了一个复合索引。

我运行此查询:

db.ProductGuideItem.find( { ProductName: { $gt: "Chicken Breast 8oz" } } ).sort({ProductName:1,_id:1}).limit(3); 

请注意,有3个“Chicken Breast 8oz”物品。

如果我运行该查询,我会得到...
鸡胸肉随机
鸡腿
鸡里脊肉

如果我正在分页并从顶部开始。查询错过了 另外2个“鸡胸肉8oz”。

因此,如果每个页面只能有3个项目,我想看到第2页,那么我应该看到..
鸡胸肉8oz
鸡胸肉8oz
鸡胸肉随机。

但我不是。这将是最后一个鸡胸肉8盎司并从那里开始。

有没有办法解决这个问题? 如果列表以相反的方式排序,我该怎么做呢?

2 个答案:

答案 0 :(得分:28)

由于我正在分页的集合有重复值,我必须在ProductName和id上创建一个复合索引。

创建复合索引

db.ProductGuideItem.ensureIndex({ ProductName:1, _id:1});

这解决了我的问题 参考:https://groups.google.com/d/msg/mongodb-user/3EZZIRJzW_A/oYH79npKZHkJ

假设您有这些值:

{a:1, b:1}
{a:2, b:1}
{a:2, b:2}
{a:2, b:3}
{a:3, b:1}

所以你为基于范围的分页(页面大小为2)执行此操作:

第一页

find().sort({a:1, b:1}).limit(2)
{a:1, b:1}
{a:2, b:1}

第二页

find().min({a:2, b:1}).sort({a:1, b:1}).skip(1).limit(2)

{a:2, b:2}
{a:2, b:3}

第3页

find().min({a:2, b:3}).sort({a:1, b:1}).skip(1).limit(2)
{a:3, b:1}

以下是$ min / max的文档: http://www.mongodb.org/display/DOCS/min+and+max+Query+Specifiers

如果您的收藏中没有重复值,则无需使用min& max或创建复合索引。你可以使用$ lt& $ GT

答案 1 :(得分:10)

您只需要在光标上调用skip

请参阅cursor skip上的MongoDB文档“这种方法可能有助于实现”分页“结果”。

此示例取自Mongodb的example

function printStudents(pageNumber, nPerPage) {
   print("Page: " + pageNumber);
   db.students.find().skip((pageNumber-1)*nPerPage).limit(nPerPage).forEach( function(student) { print(student.name + "<p>"); } );
}