Cursors and Sorting

Cursors, Sorting, Limits, and Skips

find builds a cursor object on the client and sends nothing. The query travels only when you iterate it, call toArray() or await it, and the modifiers you chain before then — sort, skip, limit, batchSize — merge into that single find command. Chaining them after iteration begins throws.

A cursor is lazy, and the modifiers are one queryJavaScript
const cur = db.books.find({ year: { $gte: 2017 } }, { _id: 0, title: 1, copies: 1 });
console.log(cur.constructor.name);
console.log(cur.sort({ copies: -1, title: 1 }).skip(1).limit(2).toArray());
db.nums.insertMany(Array.from({ length: 500 }, (_, i) => ({ n: i })));
const c2 = db.nums.find();
c2.next();
console.log("first batch:", c2.objsLeftInBatch() + 1);
Output
Cursor
[
  { title: 'Eloquent JavaScript', copies: 3 },
  { title: 'Clean Architecture', copies: 2 }
]
first batch: 101

The sort is compound: copies descending, title ascending to break ties, which puts Clean Architecture ahead of Refactoring. Always give a sort a unique tiebreaker — without one the order among equal keys is undefined and can differ between runs, so a paginated list can show the same document twice. The server applies the stages in a fixed order, filter then sort then skip then limit, which is why skip is a trap: it must produce and discard every skipped document.

101 documents is the hard-coded first batch (the server parameter internalQueryFindCommandBatchSize reports 101); after that the server fills batches up to 16 MiB, each fetched with a getMore on the same cursor id.

One find, many getMore round trips, and the two ways a cursor ends
One find, many getMore round trips, and the two ways a cursor ends

toArray() on a million-document query buys the whole result into memory at once; stream instead, since for await (const doc of cursor) pulls one batch at a time. And for pagination, replace skip with a range filter on the sort key, find({ _id: { $gt: lastId } }).sort({ _id: 1 }).limit(20), which costs the same on page ten thousand.