Access Data From a Cursor
On this page
Overview
In this guide, you can learn how to access data from a cursor with the C 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.
Whenever the C driver performs a read operation that returns multiple documents, it automatically returns those documents in a cursor.
Sample Data
The examples in this guide use the restaurants
collection in the sample_restaurants
database from the Atlas sample datasets. 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, use a while loop. The following example retrieves
all documents in the restaurants
collection and prints each document by iterating over
the cursor:
const bson_t *doc; bson_t *filter = bson_new (); mongoc_cursor_t *results = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); while (mongoc_cursor_next (results, &doc)) { char *str = bson_as_canonical_extended_json (doc, NULL); printf ("%s\n", str); bson_free (str); } mongoc_cursor_destroy (results); bson_destroy (filter);
{ "_id" : { "$oid" : "..." }, ... , "name" : "Golden Pavillion", "restaurant_id" : "40363920" } { "_id" : { "$oid" : "..." }, ... , "name" : "Morris Park Bake Shop", "restaurant_id" : "30075445" } { "_id" : { "$oid" : "..." }, ... , "name" : "Criminal Court Bldg Cafeteria", "restaurant_id" : "40364443" } { "_id" : { "$oid" : "..." }, ... , "name" : "7B Bar", "restaurant_id" : "40364518" } { "_id" : { "$oid" : "..." }, ... , "name" : "Nyac Main Dining Room", "restaurant_id" : "40364467" } ...
Retrieve Documents Individually
Retrieve documents from a cursor individually by calling the mongoc_cursor_next()
function.
This function iterates over the cursor and sets the bson
parameter to the next document in the cursor.
The following example finds all documents in a collection with a name
value
of "Dunkin' Donuts"
. It then prints the first document in the cursor by calling the
mongoc_cursor_next()
function.
const bson_t *doc; bson_t *filter = BCON_NEW ("name", BCON_UTF8 ("Dunkin' Donuts")); mongoc_cursor_t *results = mongoc_collection_find_with_opts (collection, filter, NULL, NULL); mongoc_cursor_next (results, &doc); char *str = bson_as_canonical_extended_json (doc, NULL); printf ("%s\n", str); bson_free (str); mongoc_cursor_destroy (results); bson_destroy (filter);
{ "_id" : { "$oid" : "..." }, ... , "name" : "Dunkin' Donuts", "restaurant_id" : "40392410" }
Close a Cursor
To close a cursor and release all associated resources, call the
mongoc_cursor_destroy()
function as shown in the following example:
mongoc_cursor_destroy (cursor);
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 on a capped collection,
specify the tailable
and awaitData
options when performing a find operation.
The following example creates a tailable cursor on a capped collection:
collection = mongoc_client_get_collection (client, "<database>", "<capped collection>"); bson_t *filter = bson_new (); bson_t *opts = BCON_NEW ("tailable", BCON_BOOL (true), "awaitData", BCON_BOOL (true)); mongoc_cursor_t *tailable_cursor = mongoc_collection_find_with_opts(collection, filter, opts, NULL); // Perform operations with tailable cursor here mongoc_cursor_destroy (tailable_cursor); bson_destroy (filter); bson_destroy (opts);
To learn more about tailable cursors and their usage, see the Tailable Cursors guide in the MongoDB Server manual.
Troubleshooting
"CursorNotFound cursor id not valid at server"
Cursors in MongoDB can timeout on the server if they've been open for
a long time without any operations being performed on them. This can
lead to a CursorNotFound
exception when you try to iterate through the cursor. To
resolve this issue, open a new cursor.
API Documentation
To learn more about any of the functions discussed in this guide, see the following API documentation: