Docs Menu
Docs Home
/ / /
Ruby MongoDB Driver
/

Access Data From a Cursor

On this page

  • Overview
  • Access Cursor Contents Iteratively
  • Retrieve Documents Individually
  • Retrieve All Documents
  • Tailable Cursors
  • API Documentation

In this guide, you can learn how to access data from a cursor by using the Ruby driver.

A cursor is a mechanism that returns the results of a read operation in iterable batches. Because a cursor holds only a subset of documents at any given time, cursors reduce both memory consumption and the number of requests the driver sends to the server.

You cannot access the Mongo::Cursor class directly from your application code. When you use the Ruby driver to perform a read operation, the driver returns a Mongo::Collection::View object that represents the query. Once you request query results from the Collection::View object, the driver internally stores these results in a Cursor object. Then, the Collection::View exposes the Enumerable interface, backed by the Cursor class, from which you can access the results.

The examples in this guide use the restaurants collection in the sample_restaurants database from the Atlas sample datasets. To access this collection from your Ruby application, create a Mongo::Client object that connects to an Atlas cluster and assign the following values to your database and collection variables:

database = client.use('sample_restaurants')
collection = database[:restaurants]

To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the Get Started with Atlas guide.

To iterate over the contents of a cursor, call the each method on the Mongo::Collection::View object returned by the read operation. This instructs the driver to perform the operation and return each result stored in the Mongo::Cursor.

The following example uses the find method to retrieve all documents in which the name field value is "Dunkin' Donuts". It then prints each document stored in the cursor:

cursor = collection.find(name: "Dunkin' Donuts")
cursor.each do |doc|
puts doc
end
{"_id"=>BSON::ObjectId('...'), ..., "name"=>"Dunkin' Donuts", "restaurant_id"=>"40363098"}
{"_id"=>BSON::ObjectId('...'), ..., "name"=>"Dunkin' Donuts", "restaurant_id"=>"40379573"}
{"_id"=>BSON::ObjectId('...'), ..., "name"=>"Dunkin' Donuts", "restaurant_id"=>"40392410"}
...

To retrieve documents from a cursor individually, call the first method on the Mongo::Collection::View object returned by the read operation.

The following example finds all documents in a collection that have a name value of "Dunkin' Donuts". It then prints the first document in the cursor by calling the first method.

cursor = collection.find(name: "Dunkin' Donuts")
first_doc = cursor.first
puts first_doc
{"_id"=>BSON::ObjectId('...'), ..., "name"=>"Dunkin' Donuts", "restaurant_id"=>"40363098"}

Warning

If the number and size of documents returned by your query exceeds available application memory, your program will crash. If you expect a large result set, access your cursor iteratively.

To retrieve all documents from a cursor, convert the cursor into an array by using the to_a method on its corresponding Mongo::Collection::View object.

The following example calls the to_a method to store the cursor results in an array:

cursor = collection.find(name: "Dunkin' Donuts")
array_results = cursor.to_a

When querying on a capped collection, you can use a tailable cursor that remains open after the client exhausts the results in a cursor. To create a tailable cursor, pass the cursor_type option to the find method. Set this option to :tailable.

For example, you can create a capped collection called vegetables, as shown in the following code:

db = client.use('db')
collection = db[:vegetables, capped: true, size: 1024 * 1024]
collection.create
vegetables = [
{ name: 'cauliflower' },
{ name: 'zucchini' }
]
collection.insert_many(vegetables)

Then, you can use the following code to retrieve all documents in the vegetables collection and store the results in a tailable cursor. After the cursor is exhausted, it remains open until retrieving three documents:

cursor = collection.find({}, cursor_type: :tailable)
docs_found = 0
cursor.each do |doc|
puts doc
docs_found += 1
break if docs_found >= 3
end
{"_id"=>BSON::ObjectId('...'), "name"=>"cauliflower"}
{"_id"=>BSON::ObjectId('...'), "name"=>"zucchini"}

If you insert another document into the vegetables collection, the preceding code prints the new document and does not retrieve more results from the cursor.

To learn more about tailable cursors, see Tailable Cursors in the MongoDB Server manual.

To learn more about any of the functions discussed in this guide, see the following API documentation:

Back

Count Documents