---
name: "mongoc_tutorial"
section: "3"
platform: "linux"
package: "libmongoc-doc"
version: "1.23.1-1+deb12u3"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/mongoc_tutorial"
---

# mongoc\_tutorial(3)

Tutorial This guide offers a brief introduction to the MongoDB C Driver. For more information on the C API, please refer to the API Reference.

## NAME

mongoc\_tutorial - Tutorial

This guide offers a brief introduction to the MongoDB C Driver.

For more information on the C API, please refer to the *API Reference*.

### Contents

- •

  *Tutorial*

  - •

    *Installing*

  - •

    *Starting MongoDB*

  - •

    *Include and link libmongoc in your C program*

  - •

    *Use libmongoc in a Microsoft Visual Studio Project*

  - •

    *Making a Connection*

  - •

    *Creating BSON Documents*

  - •

    *Basic CRUD Operations*

  - •

    *Executing Commands*

  - •

    *Threading*

  - •

    *Next Steps*

## INSTALLING

For detailed instructions on installing the MongoDB C Driver on a particular platform, please see the *installation guide*.

## STARTING MONGODB

To run the examples in this tutorial, MongoDB must be installed and running on **localhost** on the default port, 27017. To check if it is up and running, connect to it with the MongoDB shell.

```
$ mongo --host localhost --port 27017
MongoDB shell version: 3.0.6
connecting to: localhost:27017/test
>
```

## INCLUDE AND LINK LIBMONGOC IN YOUR C PROGRAM

### Include mongoc.h

All libmongoc's functions and types are available in one header file. Simply include **mongoc/mongoc.h**:

```
#include <mongoc/mongoc.h>
```

### CMake

The libmongoc installation includes a *CMake config-file package*, so you can use CMake's *find\_package* command to import libmongoc's CMake target and link to libmongoc (as a shared library):

CMakeLists.txt

```
# Specify the minimum version you require.
find_package (mongoc-1.0 1.7 REQUIRED)
# The "hello_mongoc.c" sample program is shared among four tests.
add_executable (hello_mongoc ../../hello_mongoc.c)
target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_shared)
```

You can also use libmongoc as a static library instead: Use the **mongo::mongoc\_static** CMake target:

```
# Specify the minimum version you require.
find_package (mongoc-1.0 1.7 REQUIRED)
# The "hello_mongoc.c" sample program is shared among four tests.
add_executable (hello_mongoc ../../hello_mongoc.c)
target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_static)
```

### pkg-config

If you're not using CMake, use *pkg-config* on the command line to set header and library paths:

```
gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0)
```

Or to statically link to libmongoc:

```
gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0)
```

### Specifying header and include paths manually

If you aren't using CMake or pkg-config, paths and libraries can be managed manually.

```
$ gcc -o hello_mongoc hello_mongoc.c \
    -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
    -lmongoc-1.0 -lbson-1.0
$ ./hello_mongoc
{ "ok" : 1.000000 }
```

For Windows users, the code can be compiled and run with the following commands. (This assumes that the MongoDB C Driver has been installed to **C:\\mongo-c-driver**; change the include directory as needed.)

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 hello_mongoc.c
C:\> hello_mongoc
{ "ok" : 1.000000 }
```

## USE LIBMONGOC IN A MICROSOFT VISUAL STUDIO PROJECT

See the *libmongoc and Visual Studio guide*.

## MAKING A CONNECTION

Access MongoDB with a *mongoc\_client\_t*. It transparently connects to standalone servers, replica sets and sharded clusters on demand. To perform operations on a database or collection, create a *mongoc\_database\_t* or *mongoc\_collection\_t* struct from the *mongoc\_client\_t*.

At the start of an application, call *mongoc\_init()* before any other libmongoc functions. At the end, call the appropriate destroy function for each collection, database, or client handle, in reverse order from how they were constructed. Call *mongoc\_cleanup()* before exiting.

The example below establishes a connection to a standalone server on **localhost**, registers the client application as "connect-example," and performs a simple command.

More information about database operations can be found in the *CRUD Operations* and *Executing Commands* sections. Examples of connecting to replica sets and sharded clusters can be found on the *Advanced Connections* page.

hello\_mongoc.c

```
#include <mongoc/mongoc.h>
int
main (int argc, char *argv[])
{
   const char *uri_string = "mongodb://localhost:27017";
   mongoc_uri_t *uri;
   mongoc_client_t *client;
   mongoc_database_t *database;
   mongoc_collection_t *collection;
   bson_t *command, reply, *insert;
   bson_error_t error;
   char *str;
   bool retval;
   /*
    * Required to initialize libmongoc's internals
    */
   mongoc_init ();
   /*
    * Optionally get MongoDB URI from command line
    */
   if (argc > 1) {
      uri_string = argv[1];
   }
   /*
    * Safely create a MongoDB URI object from the given string
    */
   uri = mongoc_uri_new_with_error (uri_string, &error);
   if (!uri) {
      fprintf (stderr,
               "failed to parse URI: %s\n"
               "error message:       %s\n",
               uri_string,
               error.message);
      return EXIT_FAILURE;
   }
   /*
    * Create a new client instance
    */
   client = mongoc_client_new_from_uri (uri);
   if (!client) {
      return EXIT_FAILURE;
   }
   /*
    * Register the application name so we can track it in the profile logs
    * on the server. This can also be done from the URI (see other examples).
    */
   mongoc_client_set_appname (client, "connect-example");
   /*
    * Get a handle on the database "db_name" and collection "coll_name"
    */
   database = mongoc_client_get_database (client, "db_name");
   collection = mongoc_client_get_collection (client, "db_name", "coll_name");
   /*
    * Do work. This example pings the database, prints the result as JSON and
    * performs an insert
    */
   command = BCON_NEW ("ping", BCON_INT32 (1));
   retval = mongoc_client_command_simple (
      client, "admin", command, NULL, &reply, &error);
   if (!retval) {
      fprintf (stderr, "%s\n", error.message);
      return EXIT_FAILURE;
   }
   str = bson_as_json (&reply, NULL);
   printf ("%s\n", str);
   insert = BCON_NEW ("hello", BCON_UTF8 ("world"));
   if (!mongoc_collection_insert_one (collection, insert, NULL, NULL, &error)) {
      fprintf (stderr, "%s\n", error.message);
   }
   bson_destroy (insert);
   bson_destroy (&reply);
   bson_destroy (command);
   bson_free (str);
   /*
    * Release our handles and clean up libmongoc
    */
   mongoc_collection_destroy (collection);
   mongoc_database_destroy (database);
   mongoc_uri_destroy (uri);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return EXIT_SUCCESS;
}
```

## CREATING BSON DOCUMENTS

Documents are stored in MongoDB's data format, BSON. The C driver uses *libbson* to create BSON documents. There are several ways to construct them: appending key-value pairs, using BCON, or parsing JSON.

### Appending BSON

A BSON document, represented as a *bson\_t* in code, can be constructed one field at a time using libbson's append functions.

For example, to create a document like this:

```
{
   born : ISODate("1906-12-09"),
   died : ISODate("1992-01-01"),
   name : {
      first : "Grace",
      last : "Hopper"
   },
   languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ],
   degrees: [ { degree: "BA", school: "Vassar" }, { degree: "PhD", school: "Yale" } ]
}
```

Use the following code:

```
#include <bson/bson.h>
int
main (int   argc,
      char *argv[])
{
   struct tm   born = { 0 };
   struct tm   died = { 0 };
   const char *lang_names[] = {"MATH-MATIC", "FLOW-MATIC", "COBOL"};
   const char *schools[] = {"Vassar", "Yale"};
   const char *degrees[] = {"BA", "PhD"};
   uint32_t    i;
   char        buf[16];
   const       char *key;
   size_t      keylen;
   bson_t     *document;
   bson_t      child;
   bson_t      child2;
   char       *str;
   document = bson_new ();
   /*
    * Append { "born" : ISODate("1906-12-09") } to the document.
    * Passing -1 for the length argument tells libbson to calculate the string length.
    */
   born.tm_year = 6;  /* years are 1900-based */
   born.tm_mon = 11;  /* months are 0-based */
   born.tm_mday = 9;
   bson_append_date_time (document, "born", -1, mktime (&born) * 1000);
   /*
    * Append { "died" : ISODate("1992-01-01") } to the document.
    */
   died.tm_year = 92;
   died.tm_mon = 0;
   died.tm_mday = 1;
   /*
    * For convenience, this macro passes length -1 by default.
    */
   BSON_APPEND_DATE_TIME (document, "died", mktime (&died) * 1000);
   /*
    * Append a subdocument.
    */
   BSON_APPEND_DOCUMENT_BEGIN (document, "name", &child);
   BSON_APPEND_UTF8 (&child, "first", "Grace");
   BSON_APPEND_UTF8 (&child, "last", "Hopper");
   bson_append_document_end (document, &child);
   /*
    * Append array of strings. Generate keys "0", "1", "2".
    */
   BSON_APPEND_ARRAY_BEGIN (document, "languages", &child);
   for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) {
      keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
      bson_append_utf8 (&child, key, (int) keylen, lang_names[i], -1);
   }
   bson_append_array_end (document, &child);
   /*
    * Array of subdocuments:
    *    degrees: [ { degree: "BA", school: "Vassar" }, ... ]
    */
   BSON_APPEND_ARRAY_BEGIN (document, "degrees", &child);
   for (i = 0; i < sizeof degrees / sizeof (char *); ++i) {
      keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
      bson_append_document_begin (&child, key, (int) keylen, &child2);
      BSON_APPEND_UTF8 (&child2, "degree", degrees[i]);
      BSON_APPEND_UTF8 (&child2, "school", schools[i]);
      bson_append_document_end (&child, &child2);
   }
   bson_append_array_end (document, &child);
   /*
    * Print the document as a JSON string.
    */
   str = bson_as_canonical_extended_json (document, NULL);
   printf ("%s\n", str);
   bson_free (str);
   /*
    * Clean up allocated bson documents.
    */
   bson_destroy (document);
   return 0;
}
```

See the *libbson documentation* for all of the types that can be appended to a *bson\_t*.

### Using BCON

*BSON C Object Notation*, BCON for short, is an alternative way of constructing BSON documents in a manner closer to the intended format. It has less type-safety than BSON's append functions but results in less code.

```
#include <bson/bson.h>
int
main (int   argc,
      char *argv[])
{
   struct tm born = { 0 };
   struct tm died = { 0 };
   bson_t   *document;
   char     *str;
   born.tm_year = 6;
   born.tm_mon = 11;
   born.tm_mday = 9;
   died.tm_year = 92;
   died.tm_mon = 0;
   died.tm_mday = 1;
   document = BCON_NEW (
      "born", BCON_DATE_TIME (mktime (&born) * 1000),
      "died", BCON_DATE_TIME (mktime (&died) * 1000),
      "name", "{",
      "first", BCON_UTF8 ("Grace"),
      "last", BCON_UTF8 ("Hopper"),
      "}",
      "languages", "[",
      BCON_UTF8 ("MATH-MATIC"),
      BCON_UTF8 ("FLOW-MATIC"),
      BCON_UTF8 ("COBOL"),
      "]",
      "degrees", "[",
      "{", "degree", BCON_UTF8 ("BA"), "school", BCON_UTF8 ("Vassar"), "}",
      "{", "degree", BCON_UTF8 ("PhD"), "school", BCON_UTF8 ("Yale"), "}",
      "]");
   /*
    * Print the document as a JSON string.
    */
   str = bson_as_canonical_extended_json (document, NULL);
   printf ("%s\n", str);
   bson_free (str);
   /*
    * Clean up allocated bson documents.
    */
   bson_destroy (document);
   return 0;
}
```

Notice that BCON can create arrays, subdocuments and arbitrary fields.

### Creating BSON from JSON

For *single* documents, BSON can be created from JSON strings via *bson\_new\_from\_json*.

```
#include <bson/bson.h>
int
main (int   argc,
      char *argv[])
{
   bson_error_t error;
   bson_t      *bson;
   char        *string;
   const char *json = "{\"name\": {\"first\":\"Grace\", \"last\":\"Hopper\"}}";
   bson = bson_new_from_json ((const uint8_t *)json, -1, &error);
   if (!bson) {
      fprintf (stderr, "%s\n", error.message);
      return EXIT_FAILURE;
   }
   string = bson_as_canonical_extended_json (bson, NULL);
   printf ("%s\n", string);
   bson_free (string);
   return 0;
}
```

To initialize BSON from a sequence of JSON documents, use *bson\_json\_reader\_t*.

## BASIC CRUD OPERATIONS

This section demonstrates the basics of using the C Driver to interact with MongoDB.

### Inserting a Document

To insert documents into a collection, first obtain a handle to a **mongoc\_collection\_t** via a **mongoc\_client\_t**. Then, use *mongoc\_collection\_insert\_one()* to add BSON documents to the collection. This example inserts into the database "mydb" and collection "mycoll".

When finished, ensure that allocated structures are freed by using their respective destroy functions.

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int   argc,
      char *argv[])
{
    mongoc_client_t *client;
    mongoc_collection_t *collection;
    bson_error_t error;
    bson_oid_t oid;
    bson_t *doc;
    mongoc_init ();
    client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
    collection = mongoc_client_get_collection (client, "mydb", "mycoll");
    doc = bson_new ();
    bson_oid_init (&oid, NULL);
    BSON_APPEND_OID (doc, "_id", &oid);
    BSON_APPEND_UTF8 (doc, "hello", "world");
    if (!mongoc_collection_insert_one (
           collection, doc, NULL, NULL, &error)) {
        fprintf (stderr, "%s\n", error.message);
    }
    bson_destroy (doc);
    mongoc_collection_destroy (collection);
    mongoc_client_destroy (client);
    mongoc_cleanup ();
    return 0;
}
```

Compile the code and run it:

```
$ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./insert
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c
C:\> insert
```

To verify that the insert succeeded, connect with the MongoDB shell.

```
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find()
{ "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" }
>
```

### Finding a Document

To query a MongoDB collection with the C driver, use the function *mongoc\_collection\_find\_with\_opts()*. This returns a *cursor* to the matching documents. The following examples iterate through the result cursors and print the matches to **stdout** as JSON strings.

Use a document as a query specifier; for example,

```
{ "color" : "red" }
```

will match any document with a field named "color" with value "red". An empty document **{}** can be used to match all documents.

This first example uses an empty query specifier to find all documents in the database "mydb" and collection "mycoll".

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_cursor_t *cursor;
   const bson_t *doc;
   bson_t *query;
   char *str;
   mongoc_init ();
   client =
      mongoc_client_new ("mongodb://localhost:27017/?appname=find-example");
   collection = mongoc_client_get_collection (client, "mydb", "mycoll");
   query = bson_new ();
   cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
   while (mongoc_cursor_next (cursor, &doc)) {
      str = bson_as_canonical_extended_json (doc, NULL);
      printf ("%s\n", str);
      bson_free (str);
   }
   bson_destroy (query);
   mongoc_cursor_destroy (cursor);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

Compile the code and run it:

```
$ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c
C:\> find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
```

To look for a specific document, add a specifier to **query**. This example adds a call to **BSON\_APPEND\_UTF8()** to look for all documents matching **{"hello" : "world"}**.

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   mongoc_cursor_t *cursor;
   const bson_t *doc;
   bson_t *query;
   char *str;
   mongoc_init ();
   client = mongoc_client_new (
      "mongodb://localhost:27017/?appname=find-specific-example");
   collection = mongoc_client_get_collection (client, "mydb", "mycoll");
   query = bson_new ();
   BSON_APPEND_UTF8 (query, "hello", "world");
   cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
   while (mongoc_cursor_next (cursor, &doc)) {
      str = bson_as_canonical_extended_json (doc, NULL);
      printf ("%s\n", str);
      bson_free (str);
   }
   bson_destroy (query);
   mongoc_cursor_destroy (cursor);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

```
$ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
```

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c
C:\> find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
```

### Updating a Document

This code snippet gives an example of using *mongoc\_collection\_update\_one()* to update the fields of a document.

Using the "mydb" database, the following example inserts an example document into the "mycoll" collection. Then, using its **\_id** field, the document is updated with different values and a new field.

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_collection_t *collection;
   mongoc_client_t *client;
   bson_error_t error;
   bson_oid_t oid;
   bson_t *doc = NULL;
   bson_t *update = NULL;
   bson_t *query = NULL;
   mongoc_init ();
   client =
      mongoc_client_new ("mongodb://localhost:27017/?appname=update-example");
   collection = mongoc_client_get_collection (client, "mydb", "mycoll");
   bson_oid_init (&oid, NULL);
   doc = BCON_NEW ("_id", BCON_OID (&oid), "key", BCON_UTF8 ("old_value"));
   if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
      fprintf (stderr, "%s\n", error.message);
      goto fail;
   }
   query = BCON_NEW ("_id", BCON_OID (&oid));
   update = BCON_NEW ("$set",
                      "{",
                      "key",
                      BCON_UTF8 ("new_value"),
                      "updated",
                      BCON_BOOL (true),
                      "}");
   if (!mongoc_collection_update_one (
          collection, query, update, NULL, NULL, &error)) {
      fprintf (stderr, "%s\n", error.message);
      goto fail;
   }
fail:
   if (doc)
      bson_destroy (doc);
   if (query)
      bson_destroy (query);
   if (update)
      bson_destroy (update);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

Compile the code and run it:

```
$ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./update
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c
C:\> update
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
```

To verify that the update succeeded, connect with the MongoDB shell.

```
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find({"updated" : true})
{ "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" }
>
```

### Deleting a Document

This example illustrates the use of *mongoc\_collection\_delete\_one()* to delete a document.

The following code inserts a sample document into the database "mydb" and collection "mycoll". Then, it deletes all documents matching **{"hello" : "world"}**.

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   bson_error_t error;
   bson_oid_t oid;
   bson_t *doc;
   mongoc_init ();
   client =
      mongoc_client_new ("mongodb://localhost:27017/?appname=delete-example");
   collection = mongoc_client_get_collection (client, "test", "test");
   doc = bson_new ();
   bson_oid_init (&oid, NULL);
   BSON_APPEND_OID (doc, "_id", &oid);
   BSON_APPEND_UTF8 (doc, "hello", "world");
   if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
      fprintf (stderr, "Insert failed: %s\n", error.message);
   }
   bson_destroy (doc);
   doc = bson_new ();
   BSON_APPEND_OID (doc, "_id", &oid);
   if (!mongoc_collection_delete_one (
          collection, doc, NULL, NULL, &error)) {
      fprintf (stderr, "Delete failed: %s\n", error.message);
   }
   bson_destroy (doc);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

Compile the code and run it:

```
$ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./delete
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c
C:\> delete
```

Use the MongoDB shell to prove that the documents have been removed successfully.

```
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.count({"hello" : "world"})
0
>
```

### Counting Documents

Counting the number of documents in a MongoDB collection is similar to performing a *find operation*. This example counts the number of documents matching **{"hello" : "world"}** in the database "mydb" and collection "mycoll".

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   bson_error_t error;
   bson_t *doc;
   int64_t count;
   mongoc_init ();
   client =
      mongoc_client_new ("mongodb://localhost:27017/?appname=count-example");
   collection = mongoc_client_get_collection (client, "mydb", "mycoll");
   doc = bson_new_from_json (
      (const uint8_t *) "{\"hello\" : \"world\"}", -1, &error);
   count = mongoc_collection_count (
      collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
   if (count < 0) {
      fprintf (stderr, "%s\n", error.message);
   } else {
      printf ("%" PRId64 "\n", count);
   }
   bson_destroy (doc);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

Compile the code and run it:

```
$ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./count
1
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c
C:\> count
1
```

## EXECUTING COMMANDS

The driver provides helper functions for executing MongoDB commands on client, database and collection structures. These functions return *cursors*; the **\_simple** variants return booleans indicating success or failure.

This example executes the *collStats* command against the collection "mycoll" in database "mydb".

```
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;
   bson_error_t error;
   bson_t *command;
   bson_t reply;
   char *str;
   mongoc_init ();
   client = mongoc_client_new (
      "mongodb://localhost:27017/?appname=executing-example");
   collection = mongoc_client_get_collection (client, "mydb", "mycoll");
   command = BCON_NEW ("collStats", BCON_UTF8 ("mycoll"));
   if (mongoc_collection_command_simple (
          collection, command, NULL, &reply, &error)) {
      str = bson_as_canonical_extended_json (&reply, NULL);
      printf ("%s\n", str);
      bson_free (str);
   } else {
      fprintf (stderr, "Failed to run command: %s\n", error.message);
   }
   bson_destroy (command);
   bson_destroy (&reply);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
   mongoc_cleanup ();
   return 0;
}
```

Compile the code and run it:

```
$ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : {  }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
```

On Windows:

```
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c
C:\> executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : {  }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
```

## THREADING

The MongoDB C Driver is thread-unaware in the vast majority of its operations. This means it is up to the programmer to guarantee thread-safety.

However, *mongoc\_client\_pool\_t* is thread-safe and is used to fetch a **mongoc\_client\_t** in a thread-safe manner. After retrieving a client from the pool, the client structure should be considered owned by the calling thread. When the thread is finished, the client should be placed back into the pool.

example-pool.c

```
/* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
 * libmongoc-1.0) */
/* ./example-pool [CONNECTION_STRING] */
#include <mongoc/mongoc.h>
#include <pthread.h>
#include <stdio.h>
static pthread_mutex_t mutex;
static bool in_shutdown = false;
static void *
worker (void *data)
{
   mongoc_client_pool_t *pool = data;
   mongoc_client_t *client;
   bson_t ping = BSON_INITIALIZER;
   bson_error_t error;
   bool r;
   BSON_APPEND_INT32 (&ping, "ping", 1);
   while (true) {
      client = mongoc_client_pool_pop (pool);
      /* Do something with client. If you are writing an HTTP server, you
       * probably only want to hold onto the client for the portion of the
       * request performing database queries.
       */
      r = mongoc_client_command_simple (
         client, "admin", &ping, NULL, NULL, &error);
      if (!r) {
         fprintf (stderr, "%s\n", error.message);
      }
      mongoc_client_pool_push (pool, client);
      pthread_mutex_lock (&mutex);
      if (in_shutdown || !r) {
         pthread_mutex_unlock (&mutex);
         break;
      }
      pthread_mutex_unlock (&mutex);
   }
   bson_destroy (&ping);
   return NULL;
}
int
main (int argc, char *argv[])
{
   const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
   mongoc_uri_t *uri;
   bson_error_t error;
   mongoc_client_pool_t *pool;
   pthread_t threads[10];
   unsigned i;
   void *ret;
   pthread_mutex_init (&mutex, NULL);
   mongoc_init ();
   if (argc > 1) {
      uri_string = argv[1];
   }
   uri = mongoc_uri_new_with_error (uri_string, &error);
   if (!uri) {
      fprintf (stderr,
               "failed to parse URI: %s\n"
               "error message:       %s\n",
               uri_string,
               error.message);
      return EXIT_FAILURE;
   }
   pool = mongoc_client_pool_new (uri);
   mongoc_client_pool_set_error_api (pool, 2);
   for (i = 0; i < 10; i++) {
      pthread_create (&threads[i], NULL, worker, pool);
   }
   sleep (10);
   pthread_mutex_lock (&mutex);
   in_shutdown = true;
   pthread_mutex_unlock (&mutex);
   for (i = 0; i < 10; i++) {
      pthread_join (threads[i], &ret);
   }
   mongoc_client_pool_destroy (pool);
   mongoc_uri_destroy (uri);
   mongoc_cleanup ();
   return EXIT_SUCCESS;
}
```

## NEXT STEPS

To find information on advanced topics, browse the rest of the *C driver guide* or the *official MongoDB documentation*.

For help with common issues, consult the *Troubleshooting* page. To report a bug or request a new feature, follow *these instructions*.

## AUTHOR

MongoDB, Inc

## COPYRIGHT

2017-present, MongoDB, Inc
