SyntaxStudy
Sign Up
MongoDB Cursors, Sort, Skip, and Limit
MongoDB Beginner 1 min read

Cursors, Sort, Skip, and Limit

When MongoDB executes a find() query, it returns a cursor rather than materialising all results immediately. The cursor fetches documents in batches from the server, which is memory-efficient for large result sets. You iterate the cursor using toArray(), forEach(), or a for-await-of loop in Node.js. Chaining sort() before limit() ensures consistent pagination. The combination of skip() and limit() implements offset-based pagination, but this can be slow on large collections because MongoDB must scan over the skipped documents. Range-based pagination — where you filter by the last seen _id — is more efficient and is the recommended approach for deep pagination.
Example
// Basic cursor iteration with for-await-of (Node.js driver)
const cursor = db.collection('products').find({ inStock: true })
for await (const doc of cursor) {
  console.log(doc.name, doc.price)
}

// toArray — fetches all results into memory
const all = await db.collection('products').find({}).toArray()

// sort: 1 = ascending, -1 = descending
db.collection('products').find().sort({ price: -1, name: 1 })

// Offset-based pagination (page 3, 10 per page)
const page = 3, pageSize = 10
db.collection('products')
  .find()
  .sort({ _id: 1 })
  .skip((page - 1) * pageSize)
  .limit(pageSize)

// Range-based pagination (more efficient for large collections)
const lastId = ObjectId("64a1f2b3c4d5e6f7a8b9c0d1")
db.collection('products')
  .find({ _id: { $gt: lastId } })
  .sort({ _id: 1 })
  .limit(10)

// Count matching documents
const count = await db.collection('products').countDocuments({ inStock: true })