在这篇文章中,我们不会谈论分页定义,尽管我们将通过另一种方法进行分页。最好具有数据库中索引的背景。
通常,没有分页功能没有网络应用程序。如果我们决定在一个页面上显示数据库中存在的所有文档,那将是疯狂的! ð
和此背后的原因是从数据库中立即读取所有文档的成本,并通过响应发送此职责。
通常,以下代码用于使用nodejs中的mongoose执行分页
await User.find().skip(0).limit(10)
此语句将查询User
模型中的用户并选择前10个文档,但不会跳过任何文档,因为skip
方法的值为0。
但是,如果我们需要“第二” 10个文档,即第11个文档到第20个文档。我们将将上述语句重写为ð
await User.find().skip(10).limit(10)
本陈述背后的成本是,它将从一开始就扫描所有文档,只能“跳过”您所传递的任何数字作为参数!这意味着,例如,如果您需要跳过前100个文档,则可以通过所有这些文档来跳过它们!
结果,随着您传递的数量的增加,性能会降低,因为使用“跳过”将使查询需要更长的时间才能执行。 ð
那么,替代方法是什么?
简单地,我们可以使用索引并与范围查询一起使用来防止扫描不需要的文档。
我们可以使用sort
方法与$lt
或$gt
操作员之间的组合应用,但是您应该将索引字段作为_id 将其传递到sort
方法。
这种方法称为基于光标的分页
基于光标的分页可以通过将光标作为objectId或时间戳来代表当前页面中最后一个文档的位置。然后可以通过将此光标传递给查询来检索下一页,该查询将返回光标之后的文档。
例如ð
await User.find( { _id: { $gt: currentCursor } } ).sort('_id').limit(10)
和准确地说,此方法还具有下跌,如果更新或删除了User
模型中的任何文档,该怎么办!在情况下,光标可能不准确,并且由于错误,某些文档可以忽略!
所以最后,我们可以说这是执行分页的两种不同的方法,每个人都有其缺点,因此您应该仔细选择哪种方法会根据您处理的情况来更好。 ð