Provided by: libmongoc-doc_1.16.1-1build2_all 

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.
Contents
• Tutorial
• Installing
• Starting MongoDB
• Include and link libmongoc in your C program
• Use libmongoc in a Microsoft Visual Studio Project
• Making a Connection
• Creating BSON Documents
• Basic CRUD Operations
• Executing Commands
• Threading
• Next Steps
Installing
For detailed instructions on installing the MongoDB C Driver on a particular platform, please see the
installation guide.
Starting MongoDB
To run the examples in this tutorial, MongoDB must be installed and running on localhost on the default
port, 27017. To check if it is up and running, connect to it with the MongoDB shell.
$ mongo --host localhost --port 27017
MongoDB shell version: 3.0.6
connecting to: localhost:27017/test
>
Include and link libmongoc in your C program
Include mongoc.h
All libmongoc's functions and types are available in one header file. Simply include mongoc/mongoc.h:
#include <mongoc/mongoc.h>
CMake
The libmongoc installation includes a CMake config-file package, so you can use CMake's find_package
command to import libmongoc's CMake target and link to libmongoc (as a shared library):
CMakeLists.txt
# Specify the minimum version you require.
find_package (mongoc-1.0 1.7 REQUIRED)
# The "hello_mongoc.c" sample program is shared among four tests.
add_executable (hello_mongoc ../../hello_mongoc.c)
target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_shared)
You can also use libmongoc as a static library instead: Use the mongo::mongoc_static CMake target:
# Specify the minimum version you require.
find_package (mongoc-1.0 1.7 REQUIRED)
# The "hello_mongoc.c" sample program is shared among four tests.
add_executable (hello_mongoc ../../hello_mongoc.c)
target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_static)
pkg-config
If you're not using CMake, use pkg-config on the command line to set header and library paths:
gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0)
Or to statically link to libmongoc:
gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0)
Specifying header and include paths manually
If you aren't using CMake or pkg-config, paths and libraries can be managed manually.
$ gcc -o hello_mongoc hello_mongoc.c \
-I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
-lmongoc-1.0 -lbson-1.0
$ ./hello_mongoc
{ "ok" : 1.000000 }
For Windows users, the code can be compiled and run with the following commands. (This assumes that the
MongoDB C Driver has been installed to C:\mongo-c-driver; change the include directory as needed.)
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 hello_mongoc.c
C:\> hello_mongoc
{ "ok" : 1.000000 }
Use libmongoc in a Microsoft Visual Studio Project
See the libmongoc and Visual Studio guide.
Making a Connection
Access MongoDB with a mongoc_client_t. It transparently connects to standalone servers, replica sets and
sharded clusters on demand. To perform operations on a database or collection, create a mongoc_database_t
or mongoc_collection_t struct from the mongoc_client_t.
At the start of an application, call mongoc_init before any other libmongoc functions. At the end, call
the appropriate destroy function for each collection, database, or client handle, in reverse order from
how they were constructed. Call mongoc_cleanup before exiting.
The example below establishes a connection to a standalone server on localhost, registers the client
application as "connect-example," and performs a simple command.
More information about database operations can be found in the CRUD Operations and Executing Commands
sections. Examples of connecting to replica sets and sharded clusters can be found on the Advanced
Connections page.
hello_mongoc.c
#include <mongoc/mongoc.h>
int
main (int argc, char *argv[])
{
const char *uri_string = "mongodb://localhost:27017";
mongoc_uri_t *uri;
mongoc_client_t *client;
mongoc_database_t *database;
mongoc_collection_t *collection;
bson_t *command, reply, *insert;
bson_error_t error;
char *str;
bool retval;
/*
* Required to initialize libmongoc's internals
*/
mongoc_init ();
/*
* Optionally get MongoDB URI from command line
*/
if (argc > 1) {
uri_string = argv[1];
}
/*
* Safely create a MongoDB URI object from the given string
*/
uri = mongoc_uri_new_with_error (uri_string, &error);
if (!uri) {
fprintf (stderr,
"failed to parse URI: %s\n"
"error message: %s\n",
uri_string,
error.message);
return EXIT_FAILURE;
}
/*
* Create a new client instance
*/
client = mongoc_client_new_from_uri (uri);
if (!client) {
return EXIT_FAILURE;
}
/*
* Register the application name so we can track it in the profile logs
* on the server. This can also be done from the URI (see other examples).
*/
mongoc_client_set_appname (client, "connect-example");
/*
* Get a handle on the database "db_name" and collection "coll_name"
*/
database = mongoc_client_get_database (client, "db_name");
collection = mongoc_client_get_collection (client, "db_name", "coll_name");
/*
* Do work. This example pings the database, prints the result as JSON and
* performs an insert
*/
command = BCON_NEW ("ping", BCON_INT32 (1));
retval = mongoc_client_command_simple (
client, "admin", command, NULL, &reply, &error);
if (!retval) {
fprintf (stderr, "%s\n", error.message);
return EXIT_FAILURE;
}
str = bson_as_json (&reply, NULL);
printf ("%s\n", str);
insert = BCON_NEW ("hello", BCON_UTF8 ("world"));
if (!mongoc_collection_insert_one (collection, insert, NULL, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
}
bson_destroy (insert);
bson_destroy (&reply);
bson_destroy (command);
bson_free (str);
/*
* Release our handles and clean up libmongoc
*/
mongoc_collection_destroy (collection);
mongoc_database_destroy (database);
mongoc_uri_destroy (uri);
mongoc_client_destroy (client);
mongoc_cleanup ();
return EXIT_SUCCESS;
}
Creating BSON Documents
Documents are stored in MongoDB's data format, BSON. The C driver uses libbson to create BSON documents.
There are several ways to construct them: appending key-value pairs, using BCON, or parsing JSON.
Appending BSON
A BSON document, represented as a bson_t in code, can be constructed one field at a time using libbson's
append functions.
For example, to create a document like this:
{
born : ISODate("1906-12-09"),
died : ISODate("1992-01-01"),
name : {
first : "Grace",
last : "Hopper"
},
languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ],
degrees: [ { degree: "BA", school: "Vassar" }, { degree: "PhD", school: "Yale" } ]
}
Use the following code:
#include <bson/bson.h>
int
main (int argc,
char *argv[])
{
struct tm born = { 0 };
struct tm died = { 0 };
const char *lang_names[] = {"MATH-MATIC", "FLOW-MATIC", "COBOL"};
const char *schools[] = {"Vassar", "Yale"};
const char *degrees[] = {"BA", "PhD"};
uint32_t i;
char buf[16];
const char *key;
size_t keylen;
bson_t *document;
bson_t child;
bson_t child2;
char *str;
document = bson_new ();
/*
* Append { "born" : ISODate("1906-12-09") } to the document.
* Passing -1 for the length argument tells libbson to calculate the string length.
*/
born.tm_year = 6; /* years are 1900-based */
born.tm_mon = 11; /* months are 0-based */
born.tm_mday = 9;
bson_append_date_time (document, "born", -1, mktime (&born) * 1000);
/*
* Append { "died" : ISODate("1992-01-01") } to the document.
*/
died.tm_year = 92;
died.tm_mon = 0;
died.tm_mday = 1;
/*
* For convenience, this macro passes length -1 by default.
*/
BSON_APPEND_DATE_TIME (document, "died", mktime (&died) * 1000);
/*
* Append a subdocument.
*/
BSON_APPEND_DOCUMENT_BEGIN (document, "name", &child);
BSON_APPEND_UTF8 (&child, "first", "Grace");
BSON_APPEND_UTF8 (&child, "last", "Hopper");
bson_append_document_end (document, &child);
/*
* Append array of strings. Generate keys "0", "1", "2".
*/
BSON_APPEND_ARRAY_BEGIN (document, "languages", &child);
for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) {
keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
bson_append_utf8 (&child, key, (int) keylen, lang_names[i], -1);
}
bson_append_array_end (document, &child);
/*
* Array of subdocuments:
* degrees: [ { degree: "BA", school: "Vassar" }, ... ]
*/
BSON_APPEND_ARRAY_BEGIN (document, "degrees", &child);
for (i = 0; i < sizeof degrees / sizeof (char *); ++i) {
keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
bson_append_document_begin (&child, key, (int) keylen, &child2);
BSON_APPEND_UTF8 (&child2, "degree", degrees[i]);
BSON_APPEND_UTF8 (&child2, "school", schools[i]);
bson_append_document_end (&child, &child2);
}
bson_append_array_end (document, &child);
/*
* Print the document as a JSON string.
*/
str = bson_as_canonical_extended_json (document, NULL);
printf ("%s\n", str);
bson_free (str);
/*
* Clean up allocated bson documents.
*/
bson_destroy (document);
return 0;
}
See the libbson documentation for all of the types that can be appended to a bson_t.
Using BCON
BSON C Object Notation, BCON for short, is an alternative way of constructing BSON documents in a manner
closer to the intended format. It has less type-safety than BSON's append functions but results in less
code.
#include <bson/bson.h>
int
main (int argc,
char *argv[])
{
struct tm born = { 0 };
struct tm died = { 0 };
bson_t *document;
char *str;
born.tm_year = 6;
born.tm_mon = 11;
born.tm_mday = 9;
died.tm_year = 92;
died.tm_mon = 0;
died.tm_mday = 1;
document = BCON_NEW (
"born", BCON_DATE_TIME (mktime (&born) * 1000),
"died", BCON_DATE_TIME (mktime (&died) * 1000),
"name", "{",
"first", BCON_UTF8 ("Grace"),
"last", BCON_UTF8 ("Hopper"),
"}",
"languages", "[",
BCON_UTF8 ("MATH-MATIC"),
BCON_UTF8 ("FLOW-MATIC"),
BCON_UTF8 ("COBOL"),
"]",
"degrees", "[",
"{", "degree", BCON_UTF8 ("BA"), "school", BCON_UTF8 ("Vassar"), "}",
"{", "degree", BCON_UTF8 ("PhD"), "school", BCON_UTF8 ("Yale"), "}",
"]");
/*
* Print the document as a JSON string.
*/
str = bson_as_canonical_extended_json (document, NULL);
printf ("%s\n", str);
bson_free (str);
/*
* Clean up allocated bson documents.
*/
bson_destroy (document);
return 0;
}
Notice that BCON can create arrays, subdocuments and arbitrary fields.
Creating BSON from JSON
For single documents, BSON can be created from JSON strings via bson_new_from_json.
#include <bson/bson.h>
int
main (int argc,
char *argv[])
{
bson_error_t error;
bson_t *bson;
char *string;
const char *json = "{\"name\": {\"first\":\"Grace\", \"last\":\"Hopper\"}}";
bson = bson_new_from_json ((const uint8_t *)json, -1, &error);
if (!bson) {
fprintf (stderr, "%s\n", error.message);
return EXIT_FAILURE;
}
string = bson_as_canonical_extended_json (bson, NULL);
printf ("%s\n", string);
bson_free (string);
return 0;
}
To initialize BSON from a sequence of JSON documents, use bson_json_reader_t.
Basic CRUD Operations
This section demonstrates the basics of using the C Driver to interact with MongoDB.
Inserting a Document
To insert documents into a collection, first obtain a handle to a mongoc_collection_t via a
mongoc_client_t. Then, use mongoc_collection_insert_one to add BSON documents to the collection. This
example inserts into the database "mydb" and collection "mycoll".
When finished, ensure that allocated structures are freed by using their respective destroy functions.
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc,
char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
mongoc_init ();
client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
doc = bson_new ();
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (doc, "_id", &oid);
BSON_APPEND_UTF8 (doc, "hello", "world");
if (!mongoc_collection_insert_one (
collection, doc, NULL, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./insert
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c
C:\> insert
To verify that the insert succeeded, connect with the MongoDB shell.
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find()
{ "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" }
>
Finding a Document
To query a MongoDB collection with the C driver, use the function mongoc_collection_find_with_opts().
This returns a cursor to the matching documents. The following examples iterate through the result
cursors and print the matches to stdout as JSON strings.
Use a document as a query specifier; for example,
{ "color" : "red" }
will match any document with a field named "color" with value "red". An empty document {} can be used to
match all documents.
This first example uses an empty query specifier to find all documents in the database "mydb" and
collection "mycoll".
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
char *str;
mongoc_init ();
client =
mongoc_client_new ("mongodb://localhost:27017/?appname=find-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
query = bson_new ();
cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_canonical_extended_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
bson_destroy (query);
mongoc_cursor_destroy (cursor);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c
C:\> find
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
To look for a specific document, add a specifier to query. This example adds a call to BSON_APPEND_UTF8()
to look for all documents matching {"hello" : "world"}.
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
mongoc_cursor_t *cursor;
const bson_t *doc;
bson_t *query;
char *str;
mongoc_init ();
client = mongoc_client_new (
"mongodb://localhost:27017/?appname=find-specific-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
query = bson_new ();
BSON_APPEND_UTF8 (query, "hello", "world");
cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
while (mongoc_cursor_next (cursor, &doc)) {
str = bson_as_canonical_extended_json (doc, NULL);
printf ("%s\n", str);
bson_free (str);
}
bson_destroy (query);
mongoc_cursor_destroy (cursor);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
$ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c
C:\> find-specific
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
Updating a Document
This code snippet gives an example of using mongoc_collection_update_one() to update the fields of a
document.
Using the "mydb" database, the following example inserts an example document into the "mycoll"
collection. Then, using its _id field, the document is updated with different values and a new field.
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_collection_t *collection;
mongoc_client_t *client;
bson_error_t error;
bson_oid_t oid;
bson_t *doc = NULL;
bson_t *update = NULL;
bson_t *query = NULL;
mongoc_init ();
client =
mongoc_client_new ("mongodb://localhost:27017/?appname=update-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
bson_oid_init (&oid, NULL);
doc = BCON_NEW ("_id", BCON_OID (&oid), "key", BCON_UTF8 ("old_value"));
if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
goto fail;
}
query = BCON_NEW ("_id", BCON_OID (&oid));
update = BCON_NEW ("$set",
"{",
"key",
BCON_UTF8 ("new_value"),
"updated",
BCON_BOOL (true),
"}");
if (!mongoc_collection_update_one (
collection, query, update, NULL, NULL, &error)) {
fprintf (stderr, "%s\n", error.message);
goto fail;
}
fail:
if (doc)
bson_destroy (doc);
if (query)
bson_destroy (query);
if (update)
bson_destroy (update);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./update
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c
C:\> update
{ "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
To verify that the update succeeded, connect with the MongoDB shell.
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.find({"updated" : true})
{ "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" }
>
Deleting a Document
This example illustrates the use of mongoc_collection_delete_one() to delete a document.
The following code inserts a sample document into the database "mydb" and collection "mycoll". Then, it
deletes all documents matching {"hello" : "world"}.
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_oid_t oid;
bson_t *doc;
mongoc_init ();
client =
mongoc_client_new ("mongodb://localhost:27017/?appname=delete-example");
collection = mongoc_client_get_collection (client, "test", "test");
doc = bson_new ();
bson_oid_init (&oid, NULL);
BSON_APPEND_OID (doc, "_id", &oid);
BSON_APPEND_UTF8 (doc, "hello", "world");
if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
fprintf (stderr, "Insert failed: %s\n", error.message);
}
bson_destroy (doc);
doc = bson_new ();
BSON_APPEND_OID (doc, "_id", &oid);
if (!mongoc_collection_delete_one (
collection, doc, NULL, NULL, &error)) {
fprintf (stderr, "Delete failed: %s\n", error.message);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./delete
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c
C:\> delete
Use the MongoDB shell to prove that the documents have been removed successfully.
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use mydb
switched to db mydb
> db.mycoll.count({"hello" : "world"})
0
>
Counting Documents
Counting the number of documents in a MongoDB collection is similar to performing a find operation. This
example counts the number of documents matching {"hello" : "world"} in the database "mydb" and collection
"mycoll".
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_t *doc;
int64_t count;
mongoc_init ();
client =
mongoc_client_new ("mongodb://localhost:27017/?appname=count-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
doc = bson_new_from_json (
(const uint8_t *) "{\"hello\" : \"world\"}", -1, &error);
count = mongoc_collection_count (
collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
if (count < 0) {
fprintf (stderr, "%s\n", error.message);
} else {
printf ("%" PRId64 "\n", count);
}
bson_destroy (doc);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./count
1
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c
C:\> count
1
Executing Commands
The driver provides helper functions for executing MongoDB commands on client, database and collection
structures. These functions return cursors; the _simple variants return booleans indicating success or
failure.
This example executes the collStats command against the collection "mycoll" in database "mydb".
#include <bson/bson.h>
#include <mongoc/mongoc.h>
#include <stdio.h>
int
main (int argc, char *argv[])
{
mongoc_client_t *client;
mongoc_collection_t *collection;
bson_error_t error;
bson_t *command;
bson_t reply;
char *str;
mongoc_init ();
client = mongoc_client_new (
"mongodb://localhost:27017/?appname=executing-example");
collection = mongoc_client_get_collection (client, "mydb", "mycoll");
command = BCON_NEW ("collStats", BCON_UTF8 ("mycoll"));
if (mongoc_collection_command_simple (
collection, command, NULL, &reply, &error)) {
str = bson_as_canonical_extended_json (&reply, NULL);
printf ("%s\n", str);
bson_free (str);
} else {
fprintf (stderr, "Failed to run command: %s\n", error.message);
}
bson_destroy (command);
bson_destroy (&reply);
mongoc_collection_destroy (collection);
mongoc_client_destroy (client);
mongoc_cleanup ();
return 0;
}
Compile the code and run it:
$ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0)
$ ./executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
On Windows:
C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c
C:\> executing
{ "ns" : "mydb.mycoll", "count" : 1, "size" : 48, "avgObjSize" : 48, "numExtents" : 1, "storageSize" : 8192,
"lastExtentSize" : 8192.000000, "paddingFactor" : 1.000000, "userFlags" : 1, "capped" : false, "nindexes" : 1,
"indexDetails" : { }, "totalIndexSize" : 8176, "indexSizes" : { "_id_" : 8176 }, "ok" : 1.000000 }
Threading
The MongoDB C Driver is thread-unaware in the vast majority of its operations. This means it is up to the
programmer to guarantee thread-safety.
However, mongoc_client_pool_t is thread-safe and is used to fetch a mongoc_client_t in a thread-safe
manner. After retrieving a client from the pool, the client structure should be considered owned by the
calling thread. When the thread is finished, the client should be placed back into the pool.
example-pool.c
/* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
* libmongoc-1.0) */
/* ./example-pool [CONNECTION_STRING] */
#include <mongoc/mongoc.h>
#include <pthread.h>
#include <stdio.h>
static pthread_mutex_t mutex;
static bool in_shutdown = false;
static void *
worker (void *data)
{
mongoc_client_pool_t *pool = data;
mongoc_client_t *client;
bson_t ping = BSON_INITIALIZER;
bson_error_t error;
bool r;
BSON_APPEND_INT32 (&ping, "ping", 1);
while (true) {
client = mongoc_client_pool_pop (pool);
/* Do something with client. If you are writing an HTTP server, you
* probably only want to hold onto the client for the portion of the
* request performing database queries.
*/
r = mongoc_client_command_simple (
client, "admin", &ping, NULL, NULL, &error);
if (!r) {
fprintf (stderr, "%s\n", error.message);
}
mongoc_client_pool_push (pool, client);
pthread_mutex_lock (&mutex);
if (in_shutdown || !r) {
pthread_mutex_unlock (&mutex);
break;
}
pthread_mutex_unlock (&mutex);
}
bson_destroy (&ping);
return NULL;
}
int
main (int argc, char *argv[])
{
const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
mongoc_uri_t *uri;
bson_error_t error;
mongoc_client_pool_t *pool;
pthread_t threads[10];
unsigned i;
void *ret;
pthread_mutex_init (&mutex, NULL);
mongoc_init ();
if (argc > 1) {
uri_string = argv[1];
}
uri = mongoc_uri_new_with_error (uri_string, &error);
if (!uri) {
fprintf (stderr,
"failed to parse URI: %s\n"
"error message: %s\n",
uri_string,
error.message);
return EXIT_FAILURE;
}
pool = mongoc_client_pool_new (uri);
mongoc_client_pool_set_error_api (pool, 2);
for (i = 0; i < 10; i++) {
pthread_create (&threads[i], NULL, worker, pool);
}
sleep (10);
pthread_mutex_lock (&mutex);
in_shutdown = true;
pthread_mutex_unlock (&mutex);
for (i = 0; i < 10; i++) {
pthread_join (threads[i], &ret);
}
mongoc_client_pool_destroy (pool);
mongoc_uri_destroy (uri);
mongoc_cleanup ();
return EXIT_SUCCESS;
}
Next Steps
To find information on advanced topics, browse the rest of the C driver guide or the official MongoDB
documentation.
For help with common issues, consult the Troubleshooting page. To report a bug or request a new feature,
follow these instructions.
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-1
• MONGODB-CR (deprecated)
• GSSAPI
• PLAIN
• X509
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)