cursor.skip()
定义
cursor.skip(<offset>)
重要
mongosh 方法
这是一个
mongosh
方法。 这不是Node.js
或其他特定于编程语言的驱动程序方法的文档。在大多数情况下,
mongosh
方法的工作方式与传统mongo
shell方法相同。 但是,某些旧方法在mongosh
中不可用。有关旧版
mongo
shell 文档,请参阅相应 MongoDB Server 版本的文档:有关 MongoDB API 驱动程序,请参阅特定语言的 MongoDB 驱动程序文档。
在游标上调用
skip()
方法来控制 MongoDB 开始返回结果的位置。此方法可能有助于实现分页结果。注意
在从数据库检索任何文档之前,必须对游标应用
skip()
。skip()
方法具有以下参数:Parameter类型说明offset
数字结果集中要跳过的文档数。
行为
将 与 结合使用skip()
sort()
如果将 skip()
和 sort()
一起使用,请务必在排序中至少包含一个包括唯一值的字段,然后再将结果传递给 skip()
。
对包含重复值的字段进行排序时,可能会在多次执行中对这些重复字段返回不一致的排序顺序,尤其是当集合正在接收写入时。
为确保排序一致,最简单方法是在排序查询中纳入 _id
字段。
有关更多信息,请参阅使用 sort() 方法进行一致排序。
将 与 结合使用skip()
limit()
将 skip()
和 limit()
链接在一起时,方法链接顺序不会影响结果。服务器始终会根据排序顺序应用跳过操作,然后再应用对返回文档数量的限制。
下面的代码示例展示了 skip()
和 limit()
的不同链接顺序,它们对同一数据集总是生成相同的查询结果:
db.myColl.find().sort({_id: 1}).skip(3).limit(6); db.myColl.find().sort({_id: 1}).limit(6).skip(3);
分页示例
运用 skip()
以下 JavaScript 函数使用 skip()
按其 _id
字段对集合进行分页:
function printStudents(pageNumber, nPerPage) { print( "Page: " + pageNumber ); db.students.find() .sort( { _id: 1 } ) .skip( pageNumber > 0 ? ( ( pageNumber - 1 ) * nPerPage ) : 0 ) .limit( nPerPage ) .forEach( student => { print( student.name ); } ); }
skip()
方法要求服务器在开始返回结果之前从输入结果集的开头开始扫描。随着偏移量的增加,skip()
的速度会变慢。
使用范围查询
范围查询可使用索引来避免扫描不需要的文档,而较之使用 skip()
进行分页,随着偏移量的增加,此方式通常性能更佳。
降序
使用此过程以通过范围查询实现分页:
选择
_id
等字段,该字段通常会随着时间的推移而朝着一致的方向变化,并且具有唯一索引以防止重复值,存储最近看到的字段值以供下一次查询。
例如,以下函数使用上述过程来输出集合中的学生姓名页面,而这些页面大致会按先使用 _id
字段的最新文档的顺序来排序(即,按降序排列):
function printStudents(startValue, nPerPage) { let endValue = null; db.students.find( { _id: { $lt: startValue } } ) .sort( { _id: -1 } ) .limit( nPerPage ) .forEach( student => { print( student.name ); endValue = student._id; } ); return endValue; }
然后,可以使用以下代码利用此分页函数打印所有学生姓名,使用 MaxKey
从最大可能的键开始:
let currentKey = MaxKey; while (currentKey !== null) { currentKey = printStudents(currentKey, 10); }
升序
按升序返回分页结果的方法与之前相类,但使用 $gt
并结合升序排序:
function printStudents(startValue, nPerPage) { let endValue = null; db.students.find( { _id: { $gt: startValue } } ) .sort( { _id: 1 } ) .limit( nPerPage ) .forEach( student => { print( student.name ); endValue = student._id; } ); return endValue; }
使用该函数的方法与此类似,但起始键为 MinKey
:
let currentKey = MinKey; while (currentKey !== null) { currentKey = printStudents(currentKey, 10); }