“文档” 菜单
文档首页
/
MongoDB Manual
/ / /

cursor.skip()

在此页面上

  • 定义
  • 行为
  • 分页示例
cursor.skip(<offset>)

重要

mongosh 方法

本页面提供 mongosh 方法的相关信息。这不是特定于语言的驱动程序(例如 Node.js)的文档。

如需了解 MongoDB API 驱动程序,请参阅特定语言的 MongoDB 驱动程序文档。

在游标上调用 skip() 方法来控制 MongoDB 开始返回结果的位置。此方法可能有助于实现分页结果。

注意

在从数据库检索任何文档之前,必须对游标应用 skip()

skip() 方法具有以下参数:

参数
类型
说明
offset
数字
结果集中要跳过的文档数。

如果将skip() sort()一起使用,请务必在将结果传递给skip()之前,在排序中至少包含一个包含唯一值的字段。

对包含重复值的字段进行排序时,可能会在多次执行中对这些重复字段返回不一致的排序顺序,尤其是当集合正在接收写入时。

为确保排序一致,最简单方法是在排序查询中纳入 _id 字段。

有关更多信息,请参阅使用 sort() 方法进行一致排序

skip()limit() 链接在一起时,方法链接顺序不会影响结果。服务器始终会根据排序顺序应用跳过操作,然后再应用对返回文档数量的限制。

下面的代码示例展示了 skip()limit() 的不同链接顺序,它们对同一数据集总是生成相同的查询结果:

db.myColl.find().sort({_id: 1}).skip(3).limit(6);
db.myColl.find().sort({_id: 1}).limit(6).skip(3);

以下 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 等字段,该字段通常会随着时间的推移而朝着一致的方向变化,并且具有唯一索引以防止重复值,

  • 使用 $ltsort() 操作符查询字段小于起始值的文档,以及

  • 存储最近看到的字段值以供下一次查询。

例如,以下函数使用上述过程来输出集合中的学生姓名页面,而这些页面大致会按先使用 _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);
}

注意

虽然 ObjectId 值应该随着时间的推移而增加,但它们不一定是单调的。这是因为他们:

  • 仅包含一秒钟的时间分辨率,因此,不能保证在同一秒内创建的 ObjectID 值的顺序,并且

  • 由可能具有不同系统时钟的客户端生成。

按升序返回分页结果的方法与之前相类,但使用 $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);
}

后退

cursor.size()

来年

cursor.sort()