How to iterate a cursor in mongosh (MongoDB Shell)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

Iteeratinge over a cursor in MongoDB Shell (mongosh) is a fundamental operation that every MongoDB user should master. This tutorial covers how to work with cursors, from the essentials of generating a cursor using queries, to efficiently iterating over them and understanding their behavior. This guide assumes basic familiarity with mongosh and MongoDB queries.

What is a Cursor in MongoDB?

In MongoDB, a cursor is a pointer to the result set of a query. When you execute a find operation, MongoDB doesn’t return the documents themselves but provides a cursor to navigate through these documents. Cursors are particularly useful for handling large datasets efficiently, without loading all documents into memory.

Basic Cursor Operations

Let’s start by looking at how to create and iterate over a simple cursor.

const myCursor = db.collection.find({});
while (myCursor.hasNext()) {
   printjson(myCursor.next());
}

This example demonstrates basic cursor iteration. Here, `db.collection.find({})` creates a cursor for all documents in the collection. `hasNext()` checks if there are more documents to process, and `next()` retrieves the next document.

Using forEach() with Cursors

The `forEach()` method provides a more elegant way to iterate over cursors.

db.collection.find({}).forEach(document => {
   printjson(document);
});

This method directly applies a provided function to each document in the cursor, making the code more readable and concise.

Cursor Pagination

Handling large data sets requires understanding pagination. This is essential for web applications to display data incrementally. Here’s how you can implement it:

let currentPage = 0;
const pageSize = 10;

const paginateCursor = () => {
   const skipAmount = currentPage * pageSize;
   db.collection.find({}).skip(skipAmount).limit(pageSize).forEach(doc => {
      printjson(doc);
   });
   currentPage++;
};

// Call paginateCursor() to fetch the next batch of documents

This method allows you to handle potentially large datasets by fetching and displaying them in chunks.

Sorting and Filtering with Cursors

Iterating over sorted and filtered results is another common task. Here is a basic example:

db.collection.find({ age: { $gt: 20 } }).sort({ name: 1 }).forEach(doc => {
   printjson(doc);
});

This query returns documents where ‘age’ is greater than 20 and sorts them by ‘name’ in ascending order, before iterating over them with `forEach()`.

Batch Processing with Cursors

In some scenarios, you may want to process documents in batches rather than one at a time. MongoDB cursors offer the `batchSize()` option for this purpose.

const cursor = db.collection.find().batchSize(50);
while (cursor.hasNext()) {
   const batch = [];
   for (let i = 0; cursor.hasNext() && i < 50; i++) {
      batch.push(cursor.next());
   }
   // Process the batch
}

This allows you to load and process documents in manageable batches, potentially improving performance and resource utilization.

Conclusion

Understanding how to iterate over cursors in mongosh is crucial for interacting with MongoDB effectively. By mastering basic iteration, pagination, sorting, filtering, and batch processing, you can efficiently navigate and manipulate large datasets. Experiment with these techniques to elevate your MongoDB skills.