Navigation

cursor.skip()

Definition

cursor.skip(<offset>)

Call the cursor.skip() method on a cursor to control where MongoDB begins returning results. This approach may be useful in implementing paginated results.

Note

You must apply cursor.skip() to the cursor before retrieving any documents from the database.

The cursor.skip() method has the following parameter:

Parameter Type Description
offset number The number of documents to skip in the results set.

Pagination Example

Using cursor.skip()

The following JavaScript function uses cursor.skip() to paginate a collection in natural order:

function printStudents(pageNumber, nPerPage) {
  print( "Page: " + pageNumber );
  db.students.find()
             .skip( pageNumber > 0 ? ( ( pageNumber - 1 ) * nPerPage ) : 0 )
             .limit( nPerPage )
             .forEach( student => {
               print( student.name );
             } );
}

The cursor.skip() method requires the server to scan from the beginning of the input results set before beginning to return results. As the offset increases, cursor.skip() will become slower.

Using Range Queries

Range queries can use indexes to avoid scanning unwanted documents, typically yielding better performance as the offset grows compared to using cursor.skip() for pagination.

Descending Order

Use this procedure to implement pagination with range queries:

  • Choose a field such as _id which generally changes in a consistent direction over time and has a unique index to prevent duplicate values,
  • Query for documents whose field is less than the start value using the $lt and cursor.sort() operators, and
  • Store the last-seen field value for the next query.

For example, the following function uses the above procedure to print pages of student names from a collection, sorted approximately in order of newest documents first using the _id field (that is, in descending order):

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;
}

You may then use the following code to print all student names using this pagination function, using MaxKey to start from the largest possible key:

let currentKey = MaxKey;
while (currentKey !== null) {
  currentKey = printStudents(currentKey, 10);
}

Note

While ObjectId values should increase over time, they are not necessarily monotonic. This is because they:

  • Only contain one second of temporal resolution, so ObjectId values created within the same second do not have a guaranteed ordering, and
  • Are generated by clients, which may have differing system clocks.

Ascending Order

Returning paginated results in ascending order is similar to the previous, but uses $gt with an ascending sort order:

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;
}

Using this function is likewise similar, but with MinKey as the starting key:

let currentKey = MinKey;
while (currentKey !== null) {
  currentKey = printStudents(currentKey, 10);
}