我可能错过了一些东西,因为我还在学习ins和 MongoDB 之外,但我需要对集合进行分页方面的帮助。
我有一个包含姓名列表的集合。
下层牛肉
鸡胸肉6盎司
鸡胸肉8盎司
鸡胸肉8盎司
鸡胸肉8盎司
鸡胸肉随机
鸡腿
鸡里脊
鸡大腿
犹太盐
我在“ProductName,_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});
这解决了我的问题。
参考: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):
第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}
第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
如果集合中没有重复值,则无需使用最小值和最大值或创建复合索引。您可以只使用 $lt 和 $gt。
更新:2024年 重新审视这一点并确保没有出现任何新的情况后。我发现这篇文章讨论了在每次页面查询后获取总计数并在 1 个请求中完成所有操作。这还考虑到文档总数在获取计数和运行查询之间是否发生变化。 https://codebeyondlimits.com/articles/pagination-in-mongodb-the-only-right-way-to-implement-it-and-avoid-common-mistakes
下面的代码将从第一页返回 10 个文档,其余页面也类似。
const perPage = 10 //10docs in single page
const page = 1 //1st page
db.collection.find({}).skip(perPage * page).limit(perPage)