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

如何在MongoDB中使用范围查询进行分页?,mongodb,pagination,Mongodb,Pagination,我可能错过了一些东西,因为我还在学习ins和 MongoDB的一部分,但我需要帮助分页集合 我有一个收藏,里面有一系列的名字 底圆牛肉 鸡胸肉6盎司 鸡胸肉8盎司 鸡胸肉8盎司 鸡胸肉8盎司 鸡胸肉随机 鸡腿 鸡里脊肉 鸡大腿 犹太食盐 我在“ProductName,\u id”上创建了一个复合索引 我运行以下查询: db.ProductGuideItem.find( { ProductName: { $gt: "Chicken Breast 8oz" } } ).sort({ProductNa

我可能错过了一些东西,因为我还在学习ins和 MongoDB的一部分,但我需要帮助分页集合

我有一个收藏,里面有一系列的名字

底圆牛肉
鸡胸肉6盎司
鸡胸肉8盎司
鸡胸肉8盎司
鸡胸肉8盎司
鸡胸肉随机
鸡腿
鸡里脊肉
鸡大腿
犹太食盐

我在“ProductName,\u id”上创建了一个复合索引

我运行以下查询:

db.ProductGuideItem.find( { ProductName: { $gt: "Chicken Breast 8oz" } } ).sort({ProductName:1,_id:1}).limit(3); 
请注意,共有3个“鸡胸肉8盎司”项目

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

如果我在寻呼,从顶部开始。这项质询可能会漏掉 另外2个“鸡胸肉8盎司”

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

但我不是。这是最后一块8盎司的鸡胸肉,从那里开始

有办法解决这个问题吗?

另外,如果列表按相反的方式排序,我将如何执行此操作?

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

创建复合索引

db.ProductGuideItem.ensureIndex({ ProductName:1, _id:1});
这解决了我的问题。
参考:

假设您有这些值:

{a:1, b:1}
{a:2, b:1}
{a:2, b:2}
{a:2, b:3}
{a:3, b:1}
因此,您可以对基于范围的分页(页面大小为2)执行此操作:

第1页

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}
find().min({a:2, b:3}).sort({a:1, b:1}).skip(1).limit(2)
{a:3, b:1}
第二页

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}
find().min({a:2, b:3}).sort({a:1, b:1}).skip(1).limit(2)
{a:3, b:1}
第三页

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}
find().min({a:2, b:3}).sort({a:1, b:1}).skip(1).limit(2)
{a:3, b:1}
以下是$min/max的文档:


如果集合中没有重复的值,则不需要使用最小值和最大值或创建复合索引。您只需使用$lt&$gt。

只需在光标上调用skip即可

请参阅MongoDB文档中的“此方法可能有助于实现“分页”结果”

这个例子取自Mongodb的

函数打印学生(页码,nPerPage){
打印(页码:+页码);
db.students.find().skip((pageNumber-1)*nPerPage).limit(nPerPage).forEach(函数(student){print(student.name+“”);});
}

您的索赔是什么?返回的三行非常好,并且与您的查询相匹配,或者您希望得到什么以及为什么?首先,请放松。很明显,我没有正确地解释这一点。如果每页只能有3个项目,我想看到第2页,那么我应该看到鸡胸肉8oz,鸡胸肉8oz,鸡胸肉随机。但我不是。这是最后一块8盎司的鸡胸肉,然后从那里开始。@Donny,我的意思是,RestRisiko在这里有一个观点(也许说得不那么巧妙,但让我们就此为止)。您可以在邮件列表上发布一个指向您的问题的链接,以便可能想在此处回答您的人可以首先检查他们计划发布的答案是否已在其他地方提出。@RestRisiko:即使此问题已在其他地方得到回答,除非已经在这里被问过和回答过,否则再问一次是完全正确的。如果你觉得再次阅读同一个问题很无聊,那么就没有必要点击链接。StackOverflow旨在成为一种社区资源,而这些问题,至少在概念上,旨在为OP提供更多的答案,而说“查看邮件列表上您的问题的答案”这样的话对实现这一点并没有特别大的帮助。@Donny V.:我同意@Adam Robinson的观点。你可以在这里问,只要这里还没有问。我不认为我们欠任何其他网站…我认为这是一个有趣的和有用的角度范围为基础的非唯一字段分页。但是,如果_id字段是查询的一部分,我认为复合索引没有多大用处。原因是_id字段是唯一的,它将自动使用默认的_id索引而不是复合索引。使用此方法时,需要强制mongodb使用索引
{ProductName:1,\u id:1}
,如果不使用此方法,则结果将无序。这不适用于向用户显示分页组件(例如
第1页、第2页、第3页、…、第10页)的分页,由于您无法随机单击
页面#N
链接,因为要使其正常工作,首先需要
页面#N-1
的最后一个
对象ID
。这更适用于“无限滚动”页面,如Google+、Facebook或Twitter。实际上,我最终创建了每个页面第一项的索引,并以此作为从一个页面跳转到另一个页面的方式。我只处理了几百件物品,所以没什么大不了的。可能无法扩展到大型集合。不确定这是否是正确的方法,因为作者声称使用skip会减慢速度。