Provided by: libmongoc-doc_1.16.1-1build2_all bug

NAME

       mongoc_reference - Index

LIBMONGOC

       A Cross Platform MongoDB Client Library for C

   Introduction
       The  MongoDB C Driver, also known as "libmongoc", is a library for using MongoDB from C applications, and
       for writing MongoDB drivers in higher-level languages.

       It depends on libbson to generate and parse BSON documents, the native data format of MongoDB.

   Installing the MongoDB C Driver (libmongoc) and BSON library (libbson)
       The following guide will step you through the  process  of  downloading,  building,  and  installing  the
       current release of the MongoDB C Driver (libmongoc) and BSON library (libbson).

   Supported Platforms
       The MongoDB C Driver is continuously tested on variety of platforms including:

       • Archlinux

       • Debian 9.2

       • macOS 10.12

       • Microsoft Windows Server 2008

       • RHEL 7.0, 7.1, 7.2

       • Ubuntu 16.04, 18.04

       • Clang 3.4, 3.5, 3.7, 3.8

       • GCC 4.6, 4.8, 4.9, 5.4, 6.3

       • MinGW-W64

       • Visual Studio 2010, 2013, 2015

       • x86, x86_64, ARM (aarch64), Power8 (ppc64le), zSeries (s390x)

   Install libmongoc with a Package Manager
       Several  Linux  distributions  provide  packages  for  libmongoc  and  its dependencies. One advantage of
       installing libmongoc with a package  manager  is  that  its  dependencies  (including  libbson)  will  be
       installed automatically.

       The libmongoc package is available on recent versions of Debian and Ubuntu.

          $ apt-get install libmongoc-1.0-0

       On Fedora, a mongo-c-driver package is available in the default repositories and can be installed with:

          $ dnf install mongo-c-driver

       On  recent  Red Hat systems, such as CentOS and RHEL 7, a mongo-c-driver package is available in the EPEL
       repository.        To        check        which         version         is         available,         see
       https://apps.fedoraproject.org/packages/mongo-c-driver. The package can be installed with:

          $ yum install mongo-c-driver

   Install libbson with a Package Manager
       The  libbson  package  is  available  on  recent  versions  of  Debian  and Ubuntu. If you have installed
       libmongoc, then libbson will have already been installed as a dependency. It is also possible to  install
       libbson without libmongoc.

          $ apt-get install libbson-1.0

       On Fedora, a libbson package is available in the default repositories and can be installed with:

          $ dnf install libbson

       On  recent  Red  Hat  systems,  such  as  CentOS  and  RHEL 7, a libbson package is available in the EPEL
       repository. To check which version  is  available,  see  https://apps.fedoraproject.org/packages/libbson.
       The package can be installed with:

          $ yum install libbson

   Building on Unix
   Prerequisites for libmongoc
       OpenSSL  is  required  for  authentication  or  for  SSL connections to MongoDB. Kerberos or LDAP support
       requires Cyrus SASL.

       To install all optional dependencies on RedHat / Fedora:

          $ sudo yum install cmake openssl-devel cyrus-sasl-devel

       On Debian / Ubuntu:

          $ sudo apt-get install cmake libssl-dev libsasl2-dev

       On FreeBSD:

          $ su -c 'pkg install cmake openssl cyrus-sasl'

   Prerequisites for libbson
       The only prerequisite for building libbson is cmake. The command lines above can be adjusted  to  install
       only cmake.

   Building from a release tarball
       Unless  you  intend to contribute to mongo-c-driver and/or libbson, you will want to build from a release
       tarball.

       The most recent release of libmongoc and libbson, both of which are included in  mongo-c-driver,  can  be
       downloaded  here.  The  instructions in this document utilize cmake's out-of-source build feature to keep
       build artifacts separate from source files.

       The following snippet will download and extract the driver, and configure it:

          $ wget https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz
          $ tar xzf mongo-c-driver-x.y.z.tar.gz
          $ cd mongo-c-driver-x.y.z
          $ mkdir cmake-build
          $ cd cmake-build
          $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..

       The -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF option is recommended, see init-cleanup. Another useful cmake
       option is -DCMAKE_BUILD_TYPE=Release for a release optimized build  and  -DCMAKE_BUILD_TYPE=Debug  for  a
       debug build. For a list of all configure options, run cmake -L ...

       If  cmake  completed  successfully,  you  will  see a considerable amount of output describing your build
       configuration. The final line of output should look something like this:

          -- Build files have been written to: /home/user/mongo-c-driver-x.y.z/cmake-build

       If cmake concludes with anything different, then there is likely an error or some other problem with  the
       build. Review the output to identify and correct the problem.

       mongo-c-driver  contains  a copy of libbson, in case your system does not already have libbson installed.
       The build will detect if libbson is not installed and use the bundled libbson.

       Additionally, it is possible to build only libbson by setting the -DENABLE_MONGOC=OFF option:

          $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF ..

       A build configuration description similar to the one above will be displayed, though with fewer  entries.
       Once the configuration is complete, the selected items can be built and installed with these commands:

          $ sudo make install

       There  are  two  ways  to  uninstall the components that have been installed.  The first is to invoke the
       uninstall program directly.  On Linux/Unix:

          $ sudo /usr/local/share/mongo-c-driver/uninstall.sh

       On Windows:

          $ C:\mongo-c-driver\share\mongo-c-driver\uninstall.bat

       The second way to uninstall is from within the build directory, assuming that it is  in  the  exact  same
       state as when the install command was invoked:

          $ sudo make uninstall

       The second approach simply invokes the uninstall program referenced in the first approach.

   Building from git
       Clone the repository and build the current master or a particular release tag:

          $ git clone https://github.com/mongodb/mongo-c-driver.git
          $ cd mongo-c-driver
          $ git checkout x.y.z  # To build a particular release
          $ python build/calc_release_version.py > VERSION_CURRENT
          $ mkdir cmake-build
          $ cd cmake-build
          $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
          $ sudo make install

   Generating the documentation
       Install Sphinx, then:

          $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
          $ make mongoc-doc

       To build only the libbson documentation:

          $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
          $ make bson-doc

       The -DENABLE_MAN_PAGES=ON and -DENABLE_HTML_DOCS=ON can also be added as options to a normal build from a
       release tarball or from git so that the documentation is built at the same time as other components.

   Building on macOS
       Install the XCode Command Line Tools:

          $ xcode-select --install

       The cmake utility is also required. First install Homebrew according to its instructions, then:

          $ brew install cmake

       Download the latest release tarball:

          $ curl -LO https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz
          $ tar xzf mongo-c-driver-x.y.z.tar.gz
          $ cd mongo-c-driver-x.y.z

       Build and install the driver:

          $ mkdir cmake-build
          $ cd cmake-build
          $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
          $ make install

       All  of  the  same variations described above (e.g., building only libbson, building documentation, etc.)
       are available when building on macOS.

   Building on Windows with Visual Studio
       Building on Windows requires Windows Vista or newer and Visual Studio 2010 or newer. Additionally,  cmake
       is required to generate Visual Studio project files.

       Let's  start by generating Visual Studio project files. The following assumes we are compiling for 64-bit
       Windows using Visual Studio 2015 Express, which can be freely  downloaded  from  Microsoft.  We  will  be
       utilizing cmake's out-of-source build feature to keep build artifacts separate from source files.

          $ cd mongo-c-driver-x.y.z
          $ mkdir cmake-build
          $ cd cmake-build
          $ cmake -G "Visual Studio 14 2015 Win64" \
              "-DCMAKE_INSTALL_PREFIX=C:\mongo-c-driver" \
              "-DCMAKE_PREFIX_PATH=C:\mongo-c-driver" \
              ..

       (Run cmake -LH .. for a list of other options.)

       Now that we have project files generated, we can either open the project in Visual Studio or compile from
       the command line. Let's build using the command line program msbuild.exe:

          $ msbuild.exe /p:Configuration=RelWithDebInfo ALL_BUILD.vcxproj

       Visual  Studio's  default  build  type  is  Debug,  but  we recommend a release build with debug info for
       production use. Now that libmongoc and libbson are compiled, let's install them using msbuild. It will be
       installed to the path specified by CMAKE_INSTALL_PREFIX.

          $ msbuild.exe INSTALL.vcxproj

       You should now see libmongoc and libbson installed in C:\mongo-c-driver

       To use the driver libraries in your program, see visual-studio-guide.

   Building on Windows with MinGW-W64 and MSYS2
       Install MSYS2 from msys2.github.io. Choose the x86_64 version, not i686.

       Open the MingGW shell with c:\msys64\ming64.exe (not the msys2_shell). Install dependencies:

          $ pacman --noconfirm -Syu
          $ pacman --noconfirm -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake
          $ pacman --noconfirm -S mingw-w64-x86_64-extra-cmake-modules make tar
          $ pacman --noconfirm -S mingw64/mingw-w64-x86_64-cyrus-sasl

       Download and untar the latest tarball.

          $ curl -LO https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz
          $ tar xzf mongo-c-driver-x.y.z.tar.gz
          $ cd mongo-c-driver-x.y.z

       Create a build directory and build and install with cmake:

          $ mkdir cmake-build
          $ cd cmake-build
          $ CC=/mingw64/bin/gcc.exe /mingw64/bin/cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX="C:/mongo-c-driver" -DCMAKE_C_FLAGS="-D__USE_MINGW_ANSI_STDIO=1" ..
          $ make install

   Additional Options for Integrators
       In the event that you are building the BSON library and/or the C driver to embed  with  other  components
       and you wish to avoid the potential for collision with components installed from a standard build or from
       a  distribution  package manager, you can make use of the BSON_OUTPUT_BASENAME and MONGOC_OUTPUT_BASENAME
       options to cmake.

          $ mkdir cmake-build
          $ cd cmake-build
          $ cmake -DBSON_OUTPUT_BASENAME=custom_bson -DMONGOC_OUTPUT_BASENAME=custom_mongoc ..

       The above command would produce libraries named libcustom_bson.so and libcustom_mongoc.so  (or  with  the
       extension  appropriate  for  the  build  platform).  Those libraries could be placed in a standard system
       directory or in an alternate location and could be linked to by specifying something like -lcustom_mongoc
       -lcustom_bson on the linker command line (possibly adjusting the specific flags to those required by your
       linker).

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

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

   ContentsTutorialInstallingStarting MongoDBInclude and link libmongoc in your C programUse libmongoc in a Microsoft Visual Studio ProjectMaking a ConnectionCreating BSON DocumentsBasic CRUD OperationsExecuting CommandsThreadingNext 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.

   Authentication
       This guide covers the use of authentication options with the MongoDB C Driver. Ensure  that  the  MongoDB
       server  is  also properly configured for authentication before making a connection. For more information,
       see the MongoDB security documentation.

       The MongoDB C driver supports several authentication mechanisms through the  use  of  MongoDB  connection
       URIs.

       By  default,  if  a  username and password are provided as part of the connection string (and an optional
       authentication database), they are used to connect  via  the  default  authentication  mechanism  of  the
       server.

       To select a specific authentication mechanism other than the default, see the list of supported mechanism
       below.

          mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");

       Currently supported values for the authMechanism connection string option are:

       • SCRAM-SHA-1MONGODB-CR (deprecated)GSSAPIPLAINX509

   Basic Authentication (SCRAM-SHA-256)
       MongoDB  4.0  introduces support for authenticating using the SCRAM protocol with the more secure SHA-256
       hash described in RFC 7677. Using this authentication mechanism means that the password is never actually
       sent over the wire when authenticating, but rather a computed proof that the client password is the  same
       as  the  password  the  server  knows.  In  MongoDB  4.0,  the C driver can determine the correct default
       authentication mechanism for users with stored SCRAM-SHA-1 and SCRAM-SHA-256 credentials:

          mongoc_client_t *client =  mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");
          /* the correct authMechanism is negotiated between the driver and server. */

       Alternatively, SCRAM-SHA-256 can be explicitly specified as an authMechanism.

          mongoc_client_t *client =  mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256&authSource=mydb");

       Passwords for SCRAM-SHA-256 undergo the preprocessing step known  as  SASLPrep  specified  in  RFC  4013.
       SASLPrep will only be performed for passwords containing non-ASCII characters.  SASLPrep requires libicu.
       If  libicu  is not available, attempting to authenticate over SCRAM-SHA-256 with non-ASCII passwords will
       result in error.

       Usernames never undergo SASLPrep.

       By default, when building the C driver libicu is linked if  available.  This  can  be  changed  with  the
       ENABLE_ICU  cmake  option. To specify an installation path of libicu, specify ICU_ROOT as a cmake option.
       See the FindICU documentation for more information.

   Basic Authentication (SCRAM-SHA-1)
       The  default  authentication  mechanism  before  MongoDB  4.0  is  SCRAM-SHA-1  (RFC  5802).  Using  this
       authentication   mechanism   means  that  the  password  is  never  actually  sent  over  the  wire  when
       authenticating, but rather a computed proof that the client password is the  same  as  the  password  the
       server knows.

          mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1&authSource=mydb");

       NOTE:
          SCRAM-SHA-1  authenticates  against  the  admin database by default. If the user is created in another
          database, then specifying the authSource is required.

   Legacy Authentication (MONGODB-CR)
       The MONGODB-CR authMechanism is deprecated and will no longer function in MongoDB 4.0.  Instead,  specify
       no authMechanism and the driver will use an authentication mechanism compatible with your server.

   GSSAPI (Kerberos) Authentication
       NOTE:
          Kerberos  support  requires  compiling  the  driver  against  cyrus-sasl on UNIX-like environments. On
          Windows, configure the driver to build against the Windows Native SSPI.

       GSSAPI (Kerberos) authentication is available in the Enterprise Edition of MongoDB. To authenticate using
       GSSAPI, the MongoDB C driver must be installed with SASL support.

       On UNIX-like environments, run the kinit command before using the following authentication methods:

          $ kinit mongodbuser@EXAMPLE.COM
          mongodbuser@EXAMPLE.COM's Password:
          $ klistCredentials cache: FILE:/tmp/krb5cc_1000
                  Principal: mongodbuser@EXAMPLE.COM

            Issued                Expires               Principal
          Feb  9 13:48:51 2013  Feb  9 23:48:51 2013  krbtgt/EXAMPLE.COM@EXAMPLE.COM

       Now authenticate using the MongoDB URI. GSSAPI authenticates against the $external virtual database, so a
       database does not need to be specified in the URI. Note that the Kerberos principal must be URL-encoded:

          mongoc_client_t *client;

          client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI");

       NOTE:
          GSSAPI authenticates against the $external database, so specifying  the  authSource  database  is  not
          required.

       The driver supports these GSSAPI properties:

       • CANONICALIZE_HOST_NAME:  This  might  be  required  with  Cyrus-SASL  when  the  hosts report different
         hostnames than what is used in the Kerberos database. The default is "false".

       • SERVICE_NAME: Use a different service name than the default, "mongodb".

       Set properties in the URL:

          mongoc_client_t *client;

          client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI&"
                                      "authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true");

       If you encounter errors such as Invalid net address, check if the application is behind  a  NAT  (Network
       Address  Translation)  firewall.  If  so,  create a ticket that uses forwardable and addressless Kerberos
       tickets. This can be done by passing -f -A to kinit.

          $ kinit -f -A mongodbuser@EXAMPLE.COM

   SASL Plain Authentication
       NOTE:
          The MongoDB C Driver must be compiled with SASL support in order to use SASL PLAIN authentication.

       MongoDB Enterprise Edition supports the SASL  PLAIN  authentication  mechanism,  initially  intended  for
       delegating  authentication  to  an  LDAP  server.  Using  the SASL PLAIN mechanism is very similar to the
       challenge response mechanism with  usernames  and  passwords.  This  authentication  mechanism  uses  the
       $external virtual database for LDAP support:

       NOTE:
          SASL  PLAIN is a clear-text authentication mechanism. It is strongly recommended to connect to MongoDB
          using SSL with certificate validation when using the PLAIN mechanism.

          mongoc_client_t *client;

          client = mongoc_client_new ("mongodb://user:password@example.com/?authMechanism=PLAIN");

       PLAIN authenticates against the  $external  database,  so  specifying  the  authSource  database  is  not
       required.

   X.509 Certificate Authentication
       NOTE:
          The  MongoDB C Driver must be compiled with SSL support for X.509 authentication support. Once this is
          done, start a server with the following options:

              $ mongod --sslMode requireSSL --sslPEMKeyFile server.pem --sslCAFile ca.pem

       The MONGODB-X509 mechanism authenticates a username derived from the distinguished subject  name  of  the
       X.509 certificate presented by the driver during SSL negotiation. This authentication method requires the
       use of SSL connections with certificate validation.

          mongoc_client_t *client;
          mongoc_ssl_opt_t ssl_opts = { 0 };

          ssl_opts.pem_file = "mycert.pem";
          ssl_opts.pem_pwd = "mycertpassword";
          ssl_opts.ca_file = "myca.pem";
          ssl_opts.ca_dir = "trust_dir";
          ssl_opts.weak_cert_validation = false;

          client = mongoc_client_new ("mongodb://x509_derived_username@localhost/?authMechanism=MONGODB-X509");
          mongoc_client_set_ssl_opts (client, &ssl_opts);

       MONGODB-X509  authenticates  against the $external database, so specifying the authSource database is not
       required. For more information on the x509_derived_username, see the MongoDB server x.509 tutorial.

       NOTE:
          The MongoDB C Driver will attempt to determine the x509 derived username when none is provided, and as
          of MongoDB 3.4 providing the username is not required at all.

   Basic Troubleshooting
   Troubleshooting Checklist
       The following is a short list of things to check when you have a problem.

       • Did you call mongoc_init() in main()? If not, you will likely see a segfault.

       • Have you leaked any clients or cursors as can be found with mongoc-stat <PID>?

       • Have packets been delivered to the server? See egress bytes from mongoc-stat <PID>.

       • Does valgrind show any leaks? Ensure you call mongoc_cleanup() at the end of your  process  to  cleanup
         lingering allocations from the MongoDB C driver.

       • If  compiling your own copy of MongoDB C Driver, consider using the cmake option -DENABLE_TRACING=ON to
         enable function tracing and hex dumps of network packets to STDERR and STDOUT.

   Performance Counters
       The MongoDB C driver comes with an optional unique feature to help developers and sysadmins  troubleshoot
       problems  in  production.   Performance  counters  are  available  for each process using the driver.  If
       available, the counters can be accessed outside of the application process via a shared  memory  segment.
       This  means  that you can graph statistics about your application process easily from tools like Munin or
       Nagios.  Your author often uses watch --interval=0.5 -d mongoc-stat $PID to monitor an application.

       Performance counters are only available  on  Linux  platforms  supporting  shared  memory  segments.   On
       supported  platforms  they  are  enabled  by  default.  Applications can be built without the counters by
       specifying the cmake option -DENABLE_SHM_COUNTERS=OFF. Additionally, if performance counters are  already
       compiled, they can be disabled at runtime by specifying the environment variable MONGOC_DISABLE_SHM.

       Performance counters keep track of the following:

       • Active and Disposed Cursors

       • Active and Disposed Clients, Client Pools, and Socket Streams.

       • Number of operations sent and received, by type.

       • Bytes transferred and received.

       • Authentication successes and failures.

       • Number of wire protocol errors.

       To  access  counters  for  a  given  process,  simply  provide  the process id to the mongoc-stat program
       installed with the MongoDB C Driver.

          $ mongoc-stat 22203
             Operations : Egress Total        : The number of sent operations.                    : 13247
             Operations : Ingress Total       : The number of received operations.                : 13246
             Operations : Egress Queries      : The number of sent Query operations.              : 13247
             Operations : Ingress Queries     : The number of received Query operations.          : 0
             Operations : Egress GetMore      : The number of sent GetMore operations.            : 0
             Operations : Ingress GetMore     : The number of received GetMore operations.        : 0
             Operations : Egress Insert       : The number of sent Insert operations.             : 0
             Operations : Ingress Insert      : The number of received Insert operations.         : 0
             Operations : Egress Delete       : The number of sent Delete operations.             : 0
             Operations : Ingress Delete      : The number of received Delete operations.         : 0
             Operations : Egress Update       : The number of sent Update operations.             : 0
             Operations : Ingress Update      : The number of received Update operations.         : 0
             Operations : Egress KillCursors  : The number of sent KillCursors operations.        : 0
             Operations : Ingress KillCursors : The number of received KillCursors operations.    : 0
             Operations : Egress Msg          : The number of sent Msg operations.                : 0
             Operations : Ingress Msg         : The number of received Msg operations.            : 0
             Operations : Egress Reply        : The number of sent Reply operations.              : 0
             Operations : Ingress Reply       : The number of received Reply operations.          : 13246
                Cursors : Active              : The number of active cursors.                     : 1
                Cursors : Disposed            : The number of disposed cursors.                   : 13246
                Clients : Active              : The number of active clients.                     : 1
                Clients : Disposed            : The number of disposed clients.                   : 0
                Streams : Active              : The number of active streams.                     : 1
                Streams : Disposed            : The number of disposed streams.                   : 0
                Streams : Egress Bytes        : The number of bytes sent.                         : 794931
                Streams : Ingress Bytes       : The number of bytes received.                     : 589694
                Streams : N Socket Timeouts   : The number of socket timeouts.                    : 0
           Client Pools : Active              : The number of active client pools.                : 1
           Client Pools : Disposed            : The number of disposed client pools.              : 0
               Protocol : Ingress Errors      : The number of protocol errors on ingress.         : 0
                   Auth : Failures            : The number of failed authentication requests.     : 0
                   Auth : Success             : The number of successful authentication requests. : 0

   Submitting a Bug Report
       Think you've found a bug? Want to see a new feature in the MongoDB C driver? Please open a  case  in  our
       issue management tool, JIRA:

       • Create an account and login.

       • Navigate to the CDRIVER project.

       • Click  Create  Issue  -  Please provide as much information as possible about the issue type and how to
         reproduce it.

       Bug reports in JIRA for all driver projects (i.e. CDRIVER,  CSHARP,  JAVA)  and  the  Core  Server  (i.e.
       SERVER) project are public.

   Guides
   Common Tasks
       Drivers  for  some  other  languages  provide  helper functions to perform certain common tasks. In the C
       Driver we must explicitly build commands to send to the server.

   Setup
       First we'll write some code to insert sample data:

       doc-common-insert.c

          /* Don't try to compile this file on its own. It's meant to be #included
             by example code */

          /* Insert some sample data */
          bool
          insert_data (mongoc_collection_t *collection)
          {
             mongoc_bulk_operation_t *bulk;
             enum N { ndocs = 4 };
             bson_t *docs[ndocs];
             bson_error_t error;
             int i = 0;
             bool ret;

             bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);

             docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
             docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
             docs[2] = BCON_NEW (
                "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
             docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");

             for (i = 0; i < ndocs; i++) {
                mongoc_bulk_operation_insert (bulk, docs[i]);
                bson_destroy (docs[i]);
                docs[i] = NULL;
             }

             ret = mongoc_bulk_operation_execute (bulk, NULL, &error);

             if (!ret) {
                fprintf (stderr, "Error inserting data: %s\n", error.message);
             }

             mongoc_bulk_operation_destroy (bulk);
             return ret;
          }

          /* A helper which we'll use a lot later on */
          void
          print_res (const bson_t *reply)
          {
             char *str;
             BSON_ASSERT (reply);
             str = bson_as_canonical_extended_json (reply, NULL);
             printf ("%s\n", str);
             bson_free (str);
          }

   explain Command
       This is how to use the explain command in MongoDB 3.2+:

       explain.c

          bool
          explain (mongoc_collection_t *collection)
          {
             bson_t *command;
             bson_t reply;
             bson_error_t error;
             bool res;

             command = BCON_NEW ("explain",
                                 "{",
                                 "find",
                                 BCON_UTF8 (COLLECTION_NAME),
                                 "filter",
                                 "{",
                                 "x",
                                 BCON_INT32 (1),
                                 "}",
                                 "}");
             res = mongoc_collection_command_simple (
                collection, command, NULL, &reply, &error);
             if (!res) {
                fprintf (stderr, "Error with explain: %s\n", error.message);
                goto cleanup;
             }

             /* Do something with the reply */
             print_res (&reply);

          cleanup:
             bson_destroy (&reply);
             bson_destroy (command);
             return res;
          }

   Running the Examples
       common-operations.c

          /*
           * Copyright 2016 MongoDB, Inc.
           *
           * Licensed under the Apache License, Version 2.0 (the "License");
           * you may not use this file except in compliance with the License.
           * You may obtain a copy of the License at
           *
           *   http://www.apache.org/licenses/LICENSE-2.0
           *
           * Unless required by applicable law or agreed to in writing, software
           * distributed under the License is distributed on an "AS IS" BASIS,
           * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           * See the License for the specific language governing permissions and
           * limitations under the License.
           */

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

          const char *COLLECTION_NAME = "things";

          #include "../doc-common-insert.c"
          #include "explain.c"

          int
          main (int argc, char *argv[])
          {
             mongoc_database_t *database = NULL;
             mongoc_client_t *client = NULL;
             mongoc_collection_t *collection = NULL;
             mongoc_uri_t *uri = NULL;
             bson_error_t error;
             char *host_and_port;
             int res = 0;

             if (argc < 2 || argc > 3) {
                fprintf (stderr,
                         "usage: %s MONGOD-1-CONNECTION-STRING "
                         "[MONGOD-2-HOST-NAME:MONGOD-2-PORT]\n",
                         argv[0]);
                fprintf (stderr,
                         "MONGOD-1-CONNECTION-STRING can be "
                         "of the following forms:\n");
                fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
                fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
                fprintf (stderr,
                         "mongodb://user:pass@localhost:27017\t"
                         "local machine on port 27017, and authenticate with username "
                         "user and password pass\n");
                return EXIT_FAILURE;
             }

             mongoc_init ();

             if (strncmp (argv[1], "mongodb://", 10) == 0) {
                host_and_port = bson_strdup (argv[1]);
             } else {
                host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
             }

             uri = mongoc_uri_new_with_error (host_and_port, &error);
             if (!uri) {
                fprintf (stderr,
                         "failed to parse URI: %s\n"
                         "error message:       %s\n",
                         host_and_port,
                         error.message);
                res = EXIT_FAILURE;
                goto cleanup;
             }

             client = mongoc_client_new_from_uri (uri);
             if (!client) {
                res = EXIT_FAILURE;
                goto cleanup;
             }

             mongoc_client_set_error_api (client, 2);
             database = mongoc_client_get_database (client, "test");
             collection = mongoc_database_get_collection (database, COLLECTION_NAME);

             printf ("Inserting data\n");
             if (!insert_data (collection)) {
                res = EXIT_FAILURE;
                goto cleanup;
             }

             printf ("explain\n");
             if (!explain (collection)) {
                res = EXIT_FAILURE;
                goto cleanup;
             }

          cleanup:
             if (collection) {
                mongoc_collection_destroy (collection);
             }

             if (database) {
                mongoc_database_destroy (database);
             }

             if (client) {
                mongoc_client_destroy (client);
             }

             if (uri) {
                mongoc_uri_destroy (uri);
             }

             bson_free (host_and_port);
             mongoc_cleanup ();
             return res;
          }

       First launch two separate instances of mongod (must be done from separate shells):

          $ mongod

          $ mkdir /tmp/db2
          $ mongod --dbpath /tmp/db2 --port 27018 # second instance

       Now compile and run the example program:

          $ cd examples/common_operations/$ gcc -Wall -o example common-operations.c $(pkg-config --cflags --libs libmongoc-1.0)$ ./example localhost:27017 localhost:27018
          Inserting data
          explain
          {
             "executionStats" : {
                "allPlansExecution" : [],
                "executionStages" : {
                   "advanced" : 19,
                   "direction" : "forward" ,
                   "docsExamined" : 76,
                   "executionTimeMillisEstimate" : 0,
                   "filter" : {
                      "x" : {
                         "$eq" : 1
                      }
                   },
                   "invalidates" : 0,
                   "isEOF" : 1,
                   "nReturned" : 19,
                   "needTime" : 58,
                   "needYield" : 0,
                   "restoreState" : 0,
                   "saveState" : 0,
                   "stage" : "COLLSCAN" ,
                   "works" : 78
                },
                "executionSuccess" : true,
                "executionTimeMillis" : 0,
                "nReturned" : 19,
                "totalDocsExamined" : 76,
                "totalKeysExamined" : 0
             },
             "ok" : 1,
             "queryPlanner" : {
                "indexFilterSet" : false,
                "namespace" : "test.things",
                "parsedQuery" : {
                   "x" : {
                      "$eq" : 1
                   }
                },
                "plannerVersion" : 1,
                "rejectedPlans" : [],
                "winningPlan" : {
                   "direction" : "forward" ,
                   "filter" : {
                      "x" : {
                         "$eq" : 1
                      }
                   },
                   "stage" : "COLLSCAN"
                }
             },
             "serverInfo" : {
                "gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25" ,
                "host" : "MacBook-Pro-57.local",
                "port" : 27017,
                "version" : "3.2.6"
             }
          }

   Advanced Connections
       The following guide contains information specific to certain types of MongoDB configurations.

       For an example of connecting to a simple standalone server, see the Tutorial. To establish  a  connection
       with authentication options enabled, see the Authentication page.

   Connecting to a Replica Set
       Connecting  to  a  replica set is much like connecting to a standalone MongoDB server. Simply specify the
       replica set name using the ?replicaSet=myreplset URI option.

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

          int
          main (int argc, char *argv[])
          {
             mongoc_client_t *client;

             mongoc_init ();

             /* Create our MongoDB Client */
             client = mongoc_client_new (
                "mongodb://host01:27017,host02:27017,host03:27017/?replicaSet=myreplset");

             /* Do some work */
             /* TODO */

             /* Clean up */
             mongoc_client_destroy (client);
             mongoc_cleanup ();

             return 0;
          }

       TIP:
          Multiple hostnames can be specified in the MongoDB connection string  URI,  with  a  comma  separating
          hosts in the seed list.

          It  is  recommended to use a seed list of members of the replica set to allow the driver to connect to
          any node.

   Connecting to a Sharded Cluster
       To connect to a sharded cluster, specify the mongos nodes the client should connect to. The C Driver will
       automatically detect that it has connected to a mongos sharding server.

       If more than one hostname is specified, a seed list will be  created  to  attempt  failover  between  the
       mongos instances.

       WARNING:
          Specifying the replicaSet parameter when connecting to a mongos sharding server is invalid.

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

          int
          main (int argc, char *argv[])
          {
             mongoc_client_t *client;

             mongoc_init ();

             /* Create our MongoDB Client */
             client = mongoc_client_new ("mongodb://myshard01:27017/");

             /* Do something with client ... */

             /* Free the client */
             mongoc_client_destroy (client);

             mongoc_cleanup ();

             return 0;
          }

   Connecting to an IPv6 Address
       The  MongoDB  C  Driver will automatically resolve IPv6 addresses from host names. However, to specify an
       IPv6 address directly, wrap the address in [].

          mongoc_uri_t *uri = mongoc_uri_new ("mongodb://[::1]:27017");

   Connecting with IPv4 and IPv6
       If connecting to a hostname that has both IPv4 and IPv6 DNS records, the  behavior  follows  RFC-6555.  A
       connection  to  the IPv6 address is attempted first. If IPv6 fails, then a connection is attempted to the
       IPv4 address. If the connection attempt to IPv6 does not complete within 250ms, then  IPv4  is  tried  in
       parallel.  Whichever succeeds connection first cancels the other. The successful DNS result is cached for
       10 minutes.

       As a consequence, attempts to connect to a mongod only listening on IPv4 may be delayed if there are both
       A (IPv4) and AAAA (IPv6) DNS records associated with the host.

       To avoid a delay, configure hostnames to match the MongoDB configuration.  That  is,  only  create  an  A
       record if the mongod is only listening on IPv4.

   Connecting to a UNIX Domain Socket
       On  UNIX-like  systems, the C Driver can connect directly to a MongoDB server using a UNIX domain socket.
       Pass the URL-encoded path to the socket, which must be suffixed with .sock. For example, to connect to  a
       domain socket at /tmp/mongodb-27017.sock:

          mongoc_uri_t *uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-27017.sock");

       Include username and password like so:

          mongoc_uri_t *uri = mongoc_uri_new ("mongodb://user:pass@%2Ftmp%2Fmongodb-27017.sock");

   Connecting to a server over SSL
       These are instructions for configuring TLS/SSL connections.

       To run a server locally (on port 27017, for example):

          $ mongod --port 27017 --sslMode requireSSL --sslPEMKeyFile server.pem --sslCAFile ca.pem

       Add /?ssl=true to the end of a client URI.

          mongoc_client_t *client = NULL;
          client = mongoc_client_new ("mongodb://localhost:27017/?ssl=true");

       MongoDB  requires  client certificates by default, unless the --sslAllowConnectionsWithoutCertificates is
       provided. The C Driver can be configured to present a client certificate using a mongoc_ssl_opt_t:

          const mongoc_ssl_opt_t *ssl_default = mongoc_ssl_opt_get_default ();
          mongoc_ssl_opt_t ssl_opts = { 0 };

          /* optionally copy in a custom trust directory or file; otherwise the default is used. */
          memcpy (&ssl_opts, ssl_default, sizeof ssl_opts);
          ssl_opts.pem_file = "client.pem"

          mongoc_client_set_ssl_opts (client, &ssl_opts);

       The client certificate provided by pem_file must be issued by  one  of  the  server  trusted  Certificate
       Authorities  listed  in --sslCAFile, or issued by a CA in the native certificate store on the server when
       omitted.

       To verify the server certificate against a specific CA, provide a PEM armored file with a CA certificate,
       or concatenated list of CA certificates using the ca_file option, or c_rehash directory structure of CAs,
       pointed to using the ca_dir option. When no ca_file or ca_dir  is  provided,  the  driver  will  use  CAs
       provided by the native platform certificate store.

       See mongoc_ssl_opt_t for more information on the various SSL related options.

   Compressing data to and from MongoDB
       MongoDB  3.4  added Snappy compression support, zlib compression in 3.6, and zstd compression in 4.2.  To
       enable compression support the client must be configured with which compressors to use:

          mongoc_client_t *client = NULL;
          client = mongoc_client_new ("mongodb://localhost:27017/?compressors=snappy,zlib,zstd");

       The compressors option specifies the priority order of compressors the client wants to use. Messages  are
       compressed if the client and server share any compressors in common.

       Note  that  the  compressor  used by the server might not be the same compressor as the client used.  For
       example, if the client uses the connection  string  compressors=zlib,snappy  the  client  will  use  zlib
       compression  to  send data (if possible), but the server might still reply using snappy, depending on how
       the server was configured.

       The driver must be built with zlib and/or snappy and/or zstd support to enable compression  support,  any
       unknown  (or  not  compiled in) compressor value will be ignored. Note: to build with zstd requires cmake
       3.12 or higher.

   Additional Connection Options
       The full list of connection options can be found in the mongoc_uri_t docs.

       Certain socket/connection related options are not configurable:
                      ─────────────────────────────────────────────────────────────────────────
                        Option          Description                    Value
                      ─────────────────────────────────────────────────────────────────────────
                        SO_KEEPALIVE    TCP Keep Alive                 Enabled
                      ─────────────────────────────────────────────────────────────────────────
                        TCP_KEEPIDLE    How long a connection  needs   300 seconds
                                        to  remain  idle  before TCP
                                        starts   sending   keepalive
                                        probes
                      ─────────────────────────────────────────────────────────────────────────
                        TCP_KEEPINTVL   The  time in seconds between   10 seconds
                                        TCP probes
                      ─────────────────────────────────────────────────────────────────────────
                        TCP_KEEPCNT     How  many  probes  to  send,   9 probes
                                        without     acknowledgement,
                                        before     dropping      the
                                        connection
                      ─────────────────────────────────────────────────────────────────────────
                        TCP_NODELAY     Send   packets  as  soon  as   Enabled (no buffering)
                                        possible  or  buffer   small
                                        packets (Nagle algorithm)
                      ┌───────────────┬──────────────────────────────┬────────────────────────┐
                      │               │                              │                        │
   Connection Pooling │               │                              │                        │
--

AUTHOR

       MongoDB, Inc

COPYRIGHT

       2017-present, MongoDB, Inc

1.16.1                                            Mar 03, 2020                               MONGOC_REFERENCE(3)