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

问题描述 投票:0回答:2

我可能错过了一些东西,因为我还在学习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 盎司,然后从那里开始。

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

mongodb pagination
2个回答
38
投票

由于我分页的集合有重复值,我必须在 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


6
投票

下面的代码将从第一页返回 10 个文档,其余页面也类似。

const perPage = 10 //10docs in single page
const page = 1 //1st page
db.collection.find({}).skip(perPage * page).limit(perPage)

© www.soinside.com 2019 - 2024. All rights reserved.