Docs Menu
Docs Home
/ / /
C Driver
/

Access Data From a Cursor

On this page

  • Overview
  • Access Cursor Contents Iteratively
  • Retrieve Documents Individually
  • Close a Cursor
  • Tailable Cursors
  • Troubleshooting
  • API Documentation

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.

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.

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 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" }

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);

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.

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.

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

Back

Distinct Field Values