Provided by: libmongoc-doc_1.26.0-1.1ubuntu2_all bug

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.

          $ mongosh --host localhost --port 27017 --quiet
          Enterprise rs0 [direct: primary] test> db.version()
          7.0.0
          >

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 in the Advanced
       Connections page, while examples of data compression can be found in the Data Compression 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;
             bson_t *document;
             bson_t child;
             bson_array_builder_t *bab;
             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_BUILDER_BEGIN (document, "languages", &bab);
             for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) {
                bson_array_builder_append_utf8 (bab, lang_names[i], -1);
             }
             bson_append_array_builder_end (document, bab);

             /*
              * Array of subdocuments:
              *    degrees: [ { degree: "BA", school: "Vassar" }, ... ]
              */
             BSON_APPEND_ARRAY_BUILDER_BEGIN (document, "degrees", &bab);
             for (i = 0; i < sizeof degrees / sizeof (char *); ++i) {
                bson_array_builder_append_document_begin (bab, &child);
                BSON_APPEND_UTF8 (&child, "degree", degrees[i]);
                BSON_APPEND_UTF8 (&child, "school", schools[i]);
                bson_array_builder_append_document_end (bab, &child);
             }
             bson_append_array_builder_end (document, bab);

             /*
              * 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. The _simple variants return booleans indicating success or failure.

       This example executes the ping command against the database "mydb".

          #include <bson/bson.h>
          #include <mongoc/mongoc.h>
          #include <stdio.h>

          int
          main (int argc, char *argv[])
          {
             mongoc_client_t *client;
             bson_error_t error;
             bson_t *command;
             bson_t reply;
             char *str;

             mongoc_init ();

             client = mongoc_client_new (
                "mongodb://localhost:27017/?appname=executing-example");

             command = BCON_NEW ("ping", BCON_INT32 (1));
             if (mongoc_client_command_simple (
                    client, "mydb", 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_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
          { "ok" : { "$numberDouble" : "1.0" }, "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } }, "signature" : { "hash" : { "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType" : "00" } }, "keyId" : { "$numberLong" : "0" } } }, "operationTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } } }

       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
          { "ok" : { "$numberDouble" : "1.0" }, "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } }, "signature" : { "hash" : { "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType" : "00" } }, "keyId" : { "$numberLong" : "0" } } }, "operationTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } } }

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