javascript - MongoDB分页的范围查询

我想在 MongoDB 上实现分页。对于我的范围查询,我考虑过使用 ObjectID:

db.tweets.find({ _id: { $lt: maxID } }, { limit: 50 })

但是,according to the docs ,ObjectID的结构意味着“ObjectId值不代表严格的插入顺序”:

The relationship between the order of ObjectId values and generation time is not strict within a single second. If multiple systems, or multiple processes or threads on a single system generate values, within a single second; ObjectId values do not represent a strict insertion order. Clock skew between clients can also result in non-strict ordering even for values, because client drivers generate ObjectId values, not the mongod process.

然后我想到了用时间戳查询:

db.tweets.find({ created: { $lt: maxDate } }, { limit: 50 })

但是,不能保证日期是唯一的 - 很可能会在同一秒内创建两个文档。这意味着分页时可能会丢失文档。

是否有任何种类的范围查询可以为我提供更高的稳定性?

最佳答案

尽管您的分页语法错误,但使用 ObjectId() 非常好。你想要:

 db.tweets.find().limit(50).sort({"_id":-1});

这表示您想要按 _id 值降序排序的推文,并且您想要最近的 50 个。您的问题是,当当前结果集发生变化时分页很棘手 - 所以而不是使用跳过下一页,您要记下结果集中最小的 _id (第 50 个最近的 _id 值,然后获取下一页:

 db.tweets.find( {_id : { "$lt" : <50th _id> } } ).limit(50).sort({"_id":-1});

这将为您提供下一个“最新”推文,而不会有新的推文扰乱您的分页。

完全不用担心 _id 的值是否严格对应于插入顺序——它会足够接近 99.999%,而且没有人真正关心亚秒级的推文来了首先 - 你甚至可能会注意到 Twitter 经常显示乱序的推文,这并不重要。

如果它很关键,那么您将不得不使用相同的技术,但使用“tweet date”,其中该日期必须是时间戳,而不仅仅是日期。

https://stackoverflow.com/questions/20960815/

相关文章:

mongodb - 在 Meteor 中运行示例的问题

mongodb - 你如何告诉 Mongo 在限制结果之前对集合进行排序?

javascript - 在 Node.js 中进行同步 MongoDB 查询的正确方法是什么?

codeigniter - 使用 MongoDB 从数组中删除特定项目

mongodb - 如何在 MongoDB shell 中中止正在运行的查询?

javascript - Mongoose 保存与插入与创建

mongodb - 在 MongoDB 中执行搜索/投影时如何重命名字段?

mongodb - 聚合框架中的 $skip 和 $limit

node.js - Nodejs 中的 Mongodb 与 Postgres

shell - 为 MongoDB shell 设置默认数据库