Access Data From a Cursor
On this page
Overview
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.
Sample Data
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.
Access Cursor Contents Iteratively
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"} ...
Retrieve Documents Individually
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"}
Retrieve All Documents
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
Tailable Cursors
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.
API Documentation
To learn more about any of the functions discussed in this guide, see the following API documentation: