1MONGOC_REFERENCE(3) libmongoc MONGOC_REFERENCE(3)
2
3
4
6 mongoc_reference - Index
7
9 A Cross Platform MongoDB Client Library for C
10
11 Introduction
12 The MongoDB C Driver, also known as "libmongoc", is a library for using
13 MongoDB from C applications, and for writing MongoDB drivers in
14 higher-level languages.
15
16 It depends on libbson to generate and parse BSON documents, the native
17 data format of MongoDB.
18
19 Installing the MongoDB C Driver (libmongoc) and BSON library (libbson)
20 The following guide will step you through the process of downloading,
21 building, and installing the current release of the MongoDB C Driver
22 (libmongoc) and BSON library (libbson).
23
24 Supported Platforms
25 The MongoDB C Driver is continuously tested on a variety of platforms
26 including:
27
28 • Archlinux
29
30 • Debian 9.2, 10.0, 11.0
31
32 • macOS 10.14 (Will be dropped in an upcoming release)
33
34 • macOS 11.0 (x86_64 and arm64)
35
36 • Microsoft Windows Server 2008, 2016
37
38 • RHEL 7.0, 7.1, 8.1, 8.2, 8.3
39
40 • Ubuntu 16.04, 18.04, 20.04
41
42 • Clang 3.4, 3.5, 3.7, 3.8, 6.0
43
44 • GCC 4.8, 4.9, 5.4, 6.3, 7.5, 8.2, 8.3, 9.4, 10.2
45
46 • MinGW-W64
47
48 • Visual Studio 2013, 2015, 2017
49
50 • x86, x86_64, ARM (aarch64), Power8 (ppc64le), zSeries (s390x)
51
52 Install libmongoc with a Package Manager
53 Several Linux distributions provide packages for libmongoc and its de‐
54 pendencies. One advantage of installing libmongoc with a package man‐
55 ager is that its dependencies (including libbson) will be installed au‐
56 tomatically. If you choose to install libmongoc from distribution pack‐
57 ages, use the package manager to confirm the version being installed is
58 sufficient for your needs.
59
60 The libmongoc package is available on recent versions of Debian and
61 Ubuntu.
62
63 $ apt-get install libmongoc-dev
64
65 The libmongoc-dev package includes headers required to build applica‐
66 tions using libmongoc. To check which version is available, run
67 apt-cache policy libmongoc-dev. To only install the libraries without
68 headers, install the libmongoc-1.0-0 package.
69
70 On Fedora, a mongo-c-driver package is available in the default reposi‐
71 tories and can be installed with:
72
73 $ dnf install mongo-c-driver-devel
74
75 The mongo-c-driver-devel package includes headers required to build ap‐
76 plications using libmongoc. To check which version is available, see
77 https://packages.fedoraproject.org/pkgs/mongo-c-driver/mongo-c-driver-devel.
78 To only install the libraries without headers, install the
79 mongo-c-driver package.
80
81 On recent Red Hat systems, such as CentOS and RHEL 7, a
82 mongo-c-driver-devel package is available in the EPEL repository. The
83 package can be installed with:
84
85 $ yum install mongo-c-driver-devel
86
87 On macOS systems with Homebrew, the mongo-c-driver package can be in‐
88 stalled with:
89
90 $ brew install mongo-c-driver
91
92 Install libbson with a Package Manager
93 The libbson package is available on recent versions of Debian and
94 Ubuntu. If you have installed libmongoc, then libbson will have already
95 been installed as a dependency. It is also possible to install libbson
96 without libmongoc.
97
98 $ apt-get install libbson-dev
99
100 The libbson-dev package includes headers required to build applications
101 using libbson. To check which version is available, run apt-cache pol‐
102 icy libbson-dev. To only install the libraries without headers, install
103 the libbson-1.0-0 package.
104
105 On Fedora, a libbson package is available in the default repositories
106 and can be installed with:
107
108 $ dnf install libbson-devel
109
110 The libbson-devel package includes headers required to build applica‐
111 tions using libbson. To check which version is available, see
112 https://packages.fedoraproject.org/pkgs/mongo-c-driver/libbson-devel.
113 To only install the libraries without headers, install the libbson
114 package.
115
116 On recent Red Hat systems, such as CentOS and RHEL 7, a libbson package
117 is available in the EPEL repository. The package can be installed
118 with:
119
120 $ yum install libbson-devel
121
122 Build environment
123 Build environment on Unix
124 Prerequisites for libmongoc
125 OpenSSL is required for authentication or for TLS connections to Mon‐
126 goDB. Kerberos or LDAP support requires Cyrus SASL.
127
128 To install all optional dependencies on RedHat / Fedora:
129
130 $ sudo yum install cmake openssl-devel cyrus-sasl-devel
131
132 On Debian / Ubuntu:
133
134 $ sudo apt-get install cmake libssl-dev libsasl2-dev
135
136 On FreeBSD:
137
138 $ su -c 'pkg install cmake openssl cyrus-sasl'
139
140 Prerequisites for libbson
141 The only prerequisite for building libbson is cmake. The command lines
142 above can be adjusted to install only cmake.
143
144 Build environment on macOS
145 Install the XCode Command Line Tools:
146
147 $ xcode-select --install
148
149 The cmake utility is also required. First install Homebrew according to
150 its instructions, then:
151
152 $ brew install cmake
153
154 Build environment on Windows with Visual Studio
155 Building on Windows requires Windows Vista or newer and Visual Studio
156 2013 or newer. Additionally, cmake is required to generate Visual Stu‐
157 dio project files. Installation of these components on Windows is be‐
158 yond the scope of this document.
159
160 Build environment on Windows with MinGW-W64 and MSYS2
161 Install MSYS2 from msys2.github.io. Choose the x86_64 version, not
162 i686.
163
164 Open the MingGW shell with c:\msys64\ming64.exe (not the msys2_shell).
165 Install dependencies:
166
167 $ pacman --noconfirm -Syu
168 $ pacman --noconfirm -S mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake
169 $ pacman --noconfirm -S mingw-w64-x86_64-extra-cmake-modules make tar
170 $ pacman --noconfirm -S mingw64/mingw-w64-x86_64-cyrus-sasl
171
172 Configuring the build
173 Before building libmongoc and/or libbson, it is necessary to configure,
174 or prepare, the build. The steps to prepare the build depend on how
175 you obtained the source code and the build platform.
176
177 Preparing a build from a release tarball
178 The most recent release of libmongoc and libbson, both of which are in‐
179 cluded in mongo-c-driver, can be downloaded here. The instructions in
180 this document utilize cmake's out-of-source build feature to keep build
181 artifacts separate from source files. While the $ prompt is used
182 throughout, the instructions below will work on Linux, macOS, and Win‐
183 dows (assuming that CMake is in the user's shell path in all cases).
184 See the subsequent sections for additional platform-specific instruc‐
185 tions.
186
187 The following snippet will download and extract the driver, and config‐
188 ure it:
189
190 $ wget https://github.com/mongodb/mongo-c-driver/releases/download/1.24.3/mongo-c-driver-1.24.3.tar.gz
191 $ tar xzf mongo-c-driver-1.24.3.tar.gz
192 $ cd mongo-c-driver-1.24.3
193 $ mkdir cmake-build
194 $ cd cmake-build
195 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
196
197 The -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF option is recommended, see
198 Initialization and cleanup. Another useful cmake option is -DC‐
199 MAKE_BUILD_TYPE=Release for a release optimized build and -DC‐
200 MAKE_BUILD_TYPE=Debug for a debug build. For a list of all configure
201 options, run cmake -L ...
202
203 If cmake completed successfully, you will see a considerable amount of
204 output describing your build configuration. The final line of output
205 should look something like this:
206
207 -- Build files have been written to: /home/user/mongo-c-driver-1.24.3/cmake-build
208
209 If cmake concludes with anything different, then it is likely an error
210 occurred.
211
212 mongo-c-driver contains a copy of libbson, in case your system does not
213 already have libbson installed. The configuration will detect if libb‐
214 son is not installed and use the bundled libbson.
215
216 Additionally, it is possible to build only libbson by setting the -DEN‐
217 ABLE_MONGOC=OFF option:
218
219 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_MONGOC=OFF ..
220
221 A build configuration description similar to the one above will be dis‐
222 played, though with fewer entries. Once the configuration is complete,
223 the selected items can be built and installed with these commands:
224
225 Preparing a build from a git repository clone
226 Clone the repository and prepare the build on the current branch or a
227 particular release tag:
228
229 $ git clone https://github.com/mongodb/mongo-c-driver.git
230 $ cd mongo-c-driver
231 $ git checkout 1.24.3 # To build a particular release
232 $ python build/calc_release_version.py > VERSION_CURRENT
233 $ mkdir cmake-build
234 $ cd cmake-build
235 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
236
237 Preparing a build on Windows with Visual Studio
238 On the Windows platform with Visual Studio, it may be necessary to
239 specify the CMake generator to use. This is especially important if
240 multiple versions of Visual Studio are installed on the system or if
241 alternate build tools (e.g., MinGW, MSYS2, Cygwin, etc.) are present on
242 the system. Specifying the generator will ensure that the build con‐
243 figuration is known with certainty, rather than relying on the
244 toolchain that CMake happens to find.
245
246 Start by generating Visual Studio project files. The following assumes
247 you are compiling for 64-bit Windows using Visual Studio 2015 Express,
248 which can be freely downloaded from Microsoft. The sample commands uti‐
249 lize cmake's out-of-source build feature to keep build artifacts sepa‐
250 rate from source files.
251
252 $ cd mongo-c-driver-1.24.3
253 $ mkdir cmake-build
254 $ cd cmake-build
255 $ cmake -G "Visual Studio 14 2015 Win64" \
256 "-DCMAKE_INSTALL_PREFIX=C:\mongo-c-driver" \
257 "-DCMAKE_PREFIX_PATH=C:\mongo-c-driver" \
258 ..
259
260 (Run cmake -LH .. for a list of other options.)
261
262 To see a complete list of the CMake generators available on your spe‐
263 cific system, use a command like this:
264
265 $ cmake --help
266
267 Executing a build
268 Building on Unix, macOS, and Windows (MinGW-W64 and MSYS2)
269 $ cmake --build .
270 $ sudo cmake --build . --target install
271
272 (Note that the sudo command may not be applicable or available depend‐
273 ing on the configuration of your system.)
274
275 In the above commands, the first relies on the default target which
276 builds all configured components. For fine grained control over what
277 gets built, the following command can be used (for Ninja and Make‐
278 file-based build systems) to list all available targets:
279
280 $ cmake --build . help
281
282 Building on Windows with Visual Studio
283 Once the project files are generated, the project can be opened di‐
284 rectly in Visual Studio or compiled from the command line.
285
286 Build using the CMake build tool mode:
287
288 $ cmake --build . --config RelWithDebInfo
289
290 Visual Studio's default build type is Debug, but we recommend a release
291 build with debug info for production use. Now that libmongoc and libb‐
292 son are compiled, install them. Components will be installed to the
293 path specified by CMAKE_INSTALL_PREFIX.
294
295 $ cmake --build . --config RelWithDebInfo --target install
296
297 You should now see libmongoc and libbson installed in C:\mongo-c-driver
298
299 For Visual Studio 2019 (16.4 and newer), this command can be used to
300 list all available targets:
301
302 $ cmake --build . -- /targets
303
304 Alternately, you can examine the files matching the glob *.vcxproj in
305 the cmake-build directory.
306
307 To use the driver libraries in your program, see Using libmongoc in a
308 Microsoft Visual Studio project.
309
310 Generating the documentation
311 Install Sphinx, then:
312
313 $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
314 $ cmake --build . --target mongoc-doc
315
316 To build only the libbson documentation:
317
318 $ cmake -DENABLE_MAN_PAGES=ON -DENABLE_HTML_DOCS=ON ..
319 $ cmake --build . --target bson-doc
320
321 The -DENABLE_MAN_PAGES=ON and -DENABLE_HTML_DOCS=ON can also be added
322 as options to a normal build from a release tarball or from git so that
323 the documentation is built at the same time as other components.
324
325 Uninstalling the installed components
326 There are two ways to uninstall the components that have been in‐
327 stalled. The first is to invoke the uninstall program directly. On
328 Linux/Unix:
329
330 $ sudo /usr/local/share/mongo-c-driver/uninstall.sh
331
332 On Windows:
333
334 $ C:\mongo-c-driver\share\mongo-c-driver\uninstall.bat
335
336 The second way to uninstall is from within the build directory, assum‐
337 ing that it is in the exact same state as when the install command was
338 invoked:
339
340 $ sudo cmake --build . --target uninstall
341
342 The second approach simply invokes the uninstall program referenced in
343 the first approach.
344
345 Dealing with Build Failures
346 If your attempt to build the C driver fails, please see the README for
347 instructions on requesting assistance.
348
349 Additional Options for Integrators
350 In the event that you are building the BSON library and/or the C driver
351 to embed with other components and you wish to avoid the potential for
352 collision with components installed from a standard build or from a
353 distribution package manager, you can make use of the BSON_OUTPUT_BASE‐
354 NAME and MONGOC_OUTPUT_BASENAME options to cmake.
355
356 $ cmake -DBSON_OUTPUT_BASENAME=custom_bson -DMONGOC_OUTPUT_BASENAME=custom_mongoc ..
357
358 The above command would produce libraries named libcustom_bson.so and
359 libcustom_mongoc.so (or with the extension appropriate for the build
360 platform). Those libraries could be placed in a standard system direc‐
361 tory or in an alternate location and could be linked to by specifying
362 something like -lcustom_mongoc -lcustom_bson on the linker command line
363 (possibly adjusting the specific flags to those required by your
364 linker).
365
366 Tutorial
367 This guide offers a brief introduction to the MongoDB C Driver.
368
369 For more information on the C API, please refer to the API Reference.
370
371 Contents
372 • Tutorial
373
374 • Installing
375
376 • Starting MongoDB
377
378 • Include and link libmongoc in your C program
379
380 • Use libmongoc in a Microsoft Visual Studio Project
381
382 • Making a Connection
383
384 • Creating BSON Documents
385
386 • Basic CRUD Operations
387
388 • Executing Commands
389
390 • Threading
391
392 • Next Steps
393
394 Installing
395 For detailed instructions on installing the MongoDB C Driver on a par‐
396 ticular platform, please see the installation guide.
397
398 Starting MongoDB
399 To run the examples in this tutorial, MongoDB must be installed and
400 running on localhost on the default port, 27017. To check if it is up
401 and running, connect to it with the MongoDB shell.
402
403 $ mongo --host localhost --port 27017
404 MongoDB shell version: 3.0.6
405 connecting to: localhost:27017/test
406 >
407
408 Include and link libmongoc in your C program
409 Include mongoc.h
410 All libmongoc's functions and types are available in one header file.
411 Simply include mongoc/mongoc.h:
412
413 #include <mongoc/mongoc.h>
414
415 CMake
416 The libmongoc installation includes a CMake config-file package, so you
417 can use CMake's find_package command to import libmongoc's CMake target
418 and link to libmongoc (as a shared library):
419
420 CMakeLists.txt
421
422 # Specify the minimum version you require.
423 find_package (mongoc-1.0 1.7 REQUIRED)
424
425 # The "hello_mongoc.c" sample program is shared among four tests.
426 add_executable (hello_mongoc ../../hello_mongoc.c)
427 target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_shared)
428
429
430 You can also use libmongoc as a static library instead: Use the
431 mongo::mongoc_static CMake target:
432
433 # Specify the minimum version you require.
434 find_package (mongoc-1.0 1.7 REQUIRED)
435
436 # The "hello_mongoc.c" sample program is shared among four tests.
437 add_executable (hello_mongoc ../../hello_mongoc.c)
438 target_link_libraries (hello_mongoc PRIVATE mongo::mongoc_static)
439
440
441 pkg-config
442 If you're not using CMake, use pkg-config on the command line to set
443 header and library paths:
444
445 gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0)
446
447
448 Or to statically link to libmongoc:
449
450 gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0)
451
452
453 Specifying header and include paths manually
454 If you aren't using CMake or pkg-config, paths and libraries can be
455 managed manually.
456
457 $ gcc -o hello_mongoc hello_mongoc.c \
458 -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
459 -lmongoc-1.0 -lbson-1.0
460 $ ./hello_mongoc
461 { "ok" : 1.000000 }
462
463 For Windows users, the code can be compiled and run with the following
464 commands. (This assumes that the MongoDB C Driver has been installed to
465 C:\mongo-c-driver; change the include directory as needed.)
466
467 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 hello_mongoc.c
468 C:\> hello_mongoc
469 { "ok" : 1.000000 }
470
471 Use libmongoc in a Microsoft Visual Studio Project
472 See the libmongoc and Visual Studio guide.
473
474 Making a Connection
475 Access MongoDB with a mongoc_client_t. It transparently connects to
476 standalone servers, replica sets and sharded clusters on demand. To
477 perform operations on a database or collection, create a
478 mongoc_database_t or mongoc_collection_t struct from the
479 mongoc_client_t.
480
481 At the start of an application, call mongoc_init() before any other
482 libmongoc functions. At the end, call the appropriate destroy function
483 for each collection, database, or client handle, in reverse order from
484 how they were constructed. Call mongoc_cleanup() before exiting.
485
486 The example below establishes a connection to a standalone server on
487 localhost, registers the client application as "connect-example," and
488 performs a simple command.
489
490 More information about database operations can be found in the CRUD Op‐
491 erations and Executing Commands sections. Examples of connecting to
492 replica sets and sharded clusters can be found on the Advanced Connec‐
493 tions page.
494
495 hello_mongoc.c
496
497 #include <mongoc/mongoc.h>
498
499 int
500 main (int argc, char *argv[])
501 {
502 const char *uri_string = "mongodb://localhost:27017";
503 mongoc_uri_t *uri;
504 mongoc_client_t *client;
505 mongoc_database_t *database;
506 mongoc_collection_t *collection;
507 bson_t *command, reply, *insert;
508 bson_error_t error;
509 char *str;
510 bool retval;
511
512 /*
513 * Required to initialize libmongoc's internals
514 */
515 mongoc_init ();
516
517 /*
518 * Optionally get MongoDB URI from command line
519 */
520 if (argc > 1) {
521 uri_string = argv[1];
522 }
523
524 /*
525 * Safely create a MongoDB URI object from the given string
526 */
527 uri = mongoc_uri_new_with_error (uri_string, &error);
528 if (!uri) {
529 fprintf (stderr,
530 "failed to parse URI: %s\n"
531 "error message: %s\n",
532 uri_string,
533 error.message);
534 return EXIT_FAILURE;
535 }
536
537 /*
538 * Create a new client instance
539 */
540 client = mongoc_client_new_from_uri (uri);
541 if (!client) {
542 return EXIT_FAILURE;
543 }
544
545 /*
546 * Register the application name so we can track it in the profile logs
547 * on the server. This can also be done from the URI (see other examples).
548 */
549 mongoc_client_set_appname (client, "connect-example");
550
551 /*
552 * Get a handle on the database "db_name" and collection "coll_name"
553 */
554 database = mongoc_client_get_database (client, "db_name");
555 collection = mongoc_client_get_collection (client, "db_name", "coll_name");
556
557 /*
558 * Do work. This example pings the database, prints the result as JSON and
559 * performs an insert
560 */
561 command = BCON_NEW ("ping", BCON_INT32 (1));
562
563 retval = mongoc_client_command_simple (
564 client, "admin", command, NULL, &reply, &error);
565
566 if (!retval) {
567 fprintf (stderr, "%s\n", error.message);
568 return EXIT_FAILURE;
569 }
570
571 str = bson_as_json (&reply, NULL);
572 printf ("%s\n", str);
573
574 insert = BCON_NEW ("hello", BCON_UTF8 ("world"));
575
576 if (!mongoc_collection_insert_one (collection, insert, NULL, NULL, &error)) {
577 fprintf (stderr, "%s\n", error.message);
578 }
579
580 bson_destroy (insert);
581 bson_destroy (&reply);
582 bson_destroy (command);
583 bson_free (str);
584
585 /*
586 * Release our handles and clean up libmongoc
587 */
588 mongoc_collection_destroy (collection);
589 mongoc_database_destroy (database);
590 mongoc_uri_destroy (uri);
591 mongoc_client_destroy (client);
592 mongoc_cleanup ();
593
594 return EXIT_SUCCESS;
595 }
596
597
598 Creating BSON Documents
599 Documents are stored in MongoDB's data format, BSON. The C driver uses
600 libbson to create BSON documents. There are several ways to construct
601 them: appending key-value pairs, using BCON, or parsing JSON.
602
603 Appending BSON
604 A BSON document, represented as a bson_t in code, can be constructed
605 one field at a time using libbson's append functions.
606
607 For example, to create a document like this:
608
609 {
610 born : ISODate("1906-12-09"),
611 died : ISODate("1992-01-01"),
612 name : {
613 first : "Grace",
614 last : "Hopper"
615 },
616 languages : [ "MATH-MATIC", "FLOW-MATIC", "COBOL" ],
617 degrees: [ { degree: "BA", school: "Vassar" }, { degree: "PhD", school: "Yale" } ]
618 }
619
620 Use the following code:
621
622 #include <bson/bson.h>
623
624 int
625 main (int argc,
626 char *argv[])
627 {
628 struct tm born = { 0 };
629 struct tm died = { 0 };
630 const char *lang_names[] = {"MATH-MATIC", "FLOW-MATIC", "COBOL"};
631 const char *schools[] = {"Vassar", "Yale"};
632 const char *degrees[] = {"BA", "PhD"};
633 uint32_t i;
634 char buf[16];
635 const char *key;
636 size_t keylen;
637 bson_t *document;
638 bson_t child;
639 bson_t child2;
640 char *str;
641
642 document = bson_new ();
643
644 /*
645 * Append { "born" : ISODate("1906-12-09") } to the document.
646 * Passing -1 for the length argument tells libbson to calculate the string length.
647 */
648 born.tm_year = 6; /* years are 1900-based */
649 born.tm_mon = 11; /* months are 0-based */
650 born.tm_mday = 9;
651 bson_append_date_time (document, "born", -1, mktime (&born) * 1000);
652
653 /*
654 * Append { "died" : ISODate("1992-01-01") } to the document.
655 */
656 died.tm_year = 92;
657 died.tm_mon = 0;
658 died.tm_mday = 1;
659
660 /*
661 * For convenience, this macro passes length -1 by default.
662 */
663 BSON_APPEND_DATE_TIME (document, "died", mktime (&died) * 1000);
664
665 /*
666 * Append a subdocument.
667 */
668 BSON_APPEND_DOCUMENT_BEGIN (document, "name", &child);
669 BSON_APPEND_UTF8 (&child, "first", "Grace");
670 BSON_APPEND_UTF8 (&child, "last", "Hopper");
671 bson_append_document_end (document, &child);
672
673 /*
674 * Append array of strings. Generate keys "0", "1", "2".
675 */
676 BSON_APPEND_ARRAY_BEGIN (document, "languages", &child);
677 for (i = 0; i < sizeof lang_names / sizeof (char *); ++i) {
678 keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
679 bson_append_utf8 (&child, key, (int) keylen, lang_names[i], -1);
680 }
681 bson_append_array_end (document, &child);
682
683 /*
684 * Array of subdocuments:
685 * degrees: [ { degree: "BA", school: "Vassar" }, ... ]
686 */
687 BSON_APPEND_ARRAY_BEGIN (document, "degrees", &child);
688 for (i = 0; i < sizeof degrees / sizeof (char *); ++i) {
689 keylen = bson_uint32_to_string (i, &key, buf, sizeof buf);
690 bson_append_document_begin (&child, key, (int) keylen, &child2);
691 BSON_APPEND_UTF8 (&child2, "degree", degrees[i]);
692 BSON_APPEND_UTF8 (&child2, "school", schools[i]);
693 bson_append_document_end (&child, &child2);
694 }
695 bson_append_array_end (document, &child);
696
697 /*
698 * Print the document as a JSON string.
699 */
700 str = bson_as_canonical_extended_json (document, NULL);
701 printf ("%s\n", str);
702 bson_free (str);
703
704 /*
705 * Clean up allocated bson documents.
706 */
707 bson_destroy (document);
708 return 0;
709 }
710
711 See the libbson documentation for all of the types that can be appended
712 to a bson_t.
713
714 Using BCON
715 BSON C Object Notation, BCON for short, is an alternative way of con‐
716 structing BSON documents in a manner closer to the intended format. It
717 has less type-safety than BSON's append functions but results in less
718 code.
719
720 #include <bson/bson.h>
721
722 int
723 main (int argc,
724 char *argv[])
725 {
726 struct tm born = { 0 };
727 struct tm died = { 0 };
728 bson_t *document;
729 char *str;
730
731 born.tm_year = 6;
732 born.tm_mon = 11;
733 born.tm_mday = 9;
734
735 died.tm_year = 92;
736 died.tm_mon = 0;
737 died.tm_mday = 1;
738
739 document = BCON_NEW (
740 "born", BCON_DATE_TIME (mktime (&born) * 1000),
741 "died", BCON_DATE_TIME (mktime (&died) * 1000),
742 "name", "{",
743 "first", BCON_UTF8 ("Grace"),
744 "last", BCON_UTF8 ("Hopper"),
745 "}",
746 "languages", "[",
747 BCON_UTF8 ("MATH-MATIC"),
748 BCON_UTF8 ("FLOW-MATIC"),
749 BCON_UTF8 ("COBOL"),
750 "]",
751 "degrees", "[",
752 "{", "degree", BCON_UTF8 ("BA"), "school", BCON_UTF8 ("Vassar"), "}",
753 "{", "degree", BCON_UTF8 ("PhD"), "school", BCON_UTF8 ("Yale"), "}",
754 "]");
755
756 /*
757 * Print the document as a JSON string.
758 */
759 str = bson_as_canonical_extended_json (document, NULL);
760 printf ("%s\n", str);
761 bson_free (str);
762
763 /*
764 * Clean up allocated bson documents.
765 */
766 bson_destroy (document);
767 return 0;
768 }
769
770 Notice that BCON can create arrays, subdocuments and arbitrary fields.
771
772 Creating BSON from JSON
773 For single documents, BSON can be created from JSON strings via
774 bson_new_from_json.
775
776 #include <bson/bson.h>
777
778 int
779 main (int argc,
780 char *argv[])
781 {
782 bson_error_t error;
783 bson_t *bson;
784 char *string;
785
786 const char *json = "{\"name\": {\"first\":\"Grace\", \"last\":\"Hopper\"}}";
787 bson = bson_new_from_json ((const uint8_t *)json, -1, &error);
788
789 if (!bson) {
790 fprintf (stderr, "%s\n", error.message);
791 return EXIT_FAILURE;
792 }
793
794 string = bson_as_canonical_extended_json (bson, NULL);
795 printf ("%s\n", string);
796 bson_free (string);
797
798 return 0;
799 }
800
801 To initialize BSON from a sequence of JSON documents, use
802 bson_json_reader_t.
803
804 Basic CRUD Operations
805 This section demonstrates the basics of using the C Driver to interact
806 with MongoDB.
807
808 Inserting a Document
809 To insert documents into a collection, first obtain a handle to a mon‐
810 goc_collection_t via a mongoc_client_t. Then, use
811 mongoc_collection_insert_one() to add BSON documents to the collection.
812 This example inserts into the database "mydb" and collection "mycoll".
813
814 When finished, ensure that allocated structures are freed by using
815 their respective destroy functions.
816
817 #include <bson/bson.h>
818 #include <mongoc/mongoc.h>
819 #include <stdio.h>
820
821 int
822 main (int argc,
823 char *argv[])
824 {
825 mongoc_client_t *client;
826 mongoc_collection_t *collection;
827 bson_error_t error;
828 bson_oid_t oid;
829 bson_t *doc;
830
831 mongoc_init ();
832
833 client = mongoc_client_new ("mongodb://localhost:27017/?appname=insert-example");
834 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
835
836 doc = bson_new ();
837 bson_oid_init (&oid, NULL);
838 BSON_APPEND_OID (doc, "_id", &oid);
839 BSON_APPEND_UTF8 (doc, "hello", "world");
840
841 if (!mongoc_collection_insert_one (
842 collection, doc, NULL, NULL, &error)) {
843 fprintf (stderr, "%s\n", error.message);
844 }
845
846 bson_destroy (doc);
847 mongoc_collection_destroy (collection);
848 mongoc_client_destroy (client);
849 mongoc_cleanup ();
850
851 return 0;
852 }
853
854 Compile the code and run it:
855
856 $ gcc -o insert insert.c $(pkg-config --cflags --libs libmongoc-1.0)
857 $ ./insert
858
859 On Windows:
860
861 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 insert.c
862 C:\> insert
863
864 To verify that the insert succeeded, connect with the MongoDB shell.
865
866 $ mongo
867 MongoDB shell version: 3.0.6
868 connecting to: test
869 > use mydb
870 switched to db mydb
871 > db.mycoll.find()
872 { "_id" : ObjectId("55ef43766cb5f36a3bae6ee4"), "hello" : "world" }
873 >
874
875 Finding a Document
876 To query a MongoDB collection with the C driver, use the function
877 mongoc_collection_find_with_opts(). This returns a cursor to the match‐
878 ing documents. The following examples iterate through the result cur‐
879 sors and print the matches to stdout as JSON strings.
880
881 Use a document as a query specifier; for example,
882
883 { "color" : "red" }
884
885 will match any document with a field named "color" with value "red". An
886 empty document {} can be used to match all documents.
887
888 This first example uses an empty query specifier to find all documents
889 in the database "mydb" and collection "mycoll".
890
891 #include <bson/bson.h>
892 #include <mongoc/mongoc.h>
893 #include <stdio.h>
894
895 int
896 main (int argc, char *argv[])
897 {
898 mongoc_client_t *client;
899 mongoc_collection_t *collection;
900 mongoc_cursor_t *cursor;
901 const bson_t *doc;
902 bson_t *query;
903 char *str;
904
905 mongoc_init ();
906
907 client =
908 mongoc_client_new ("mongodb://localhost:27017/?appname=find-example");
909 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
910 query = bson_new ();
911 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
912
913 while (mongoc_cursor_next (cursor, &doc)) {
914 str = bson_as_canonical_extended_json (doc, NULL);
915 printf ("%s\n", str);
916 bson_free (str);
917 }
918
919 bson_destroy (query);
920 mongoc_cursor_destroy (cursor);
921 mongoc_collection_destroy (collection);
922 mongoc_client_destroy (client);
923 mongoc_cleanup ();
924
925 return 0;
926 }
927
928 Compile the code and run it:
929
930 $ gcc -o find find.c $(pkg-config --cflags --libs libmongoc-1.0)
931 $ ./find
932 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
933
934 On Windows:
935
936 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find.c
937 C:\> find
938 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
939
940 To look for a specific document, add a specifier to query. This example
941 adds a call to BSON_APPEND_UTF8() to look for all documents matching
942 {"hello" : "world"}.
943
944 #include <bson/bson.h>
945 #include <mongoc/mongoc.h>
946 #include <stdio.h>
947
948 int
949 main (int argc, char *argv[])
950 {
951 mongoc_client_t *client;
952 mongoc_collection_t *collection;
953 mongoc_cursor_t *cursor;
954 const bson_t *doc;
955 bson_t *query;
956 char *str;
957
958 mongoc_init ();
959
960 client = mongoc_client_new (
961 "mongodb://localhost:27017/?appname=find-specific-example");
962 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
963 query = bson_new ();
964 BSON_APPEND_UTF8 (query, "hello", "world");
965
966 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
967
968 while (mongoc_cursor_next (cursor, &doc)) {
969 str = bson_as_canonical_extended_json (doc, NULL);
970 printf ("%s\n", str);
971 bson_free (str);
972 }
973
974 bson_destroy (query);
975 mongoc_cursor_destroy (cursor);
976 mongoc_collection_destroy (collection);
977 mongoc_client_destroy (client);
978 mongoc_cleanup ();
979
980 return 0;
981 }
982
983 $ gcc -o find-specific find-specific.c $(pkg-config --cflags --libs libmongoc-1.0)
984 $ ./find-specific
985 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
986
987 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 find-specific.c
988 C:\> find-specific
989 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
990
991 Updating a Document
992 This code snippet gives an example of using
993 mongoc_collection_update_one() to update the fields of a document.
994
995 Using the "mydb" database, the following example inserts an example
996 document into the "mycoll" collection. Then, using its _id field, the
997 document is updated with different values and a new field.
998
999 #include <bson/bson.h>
1000 #include <mongoc/mongoc.h>
1001 #include <stdio.h>
1002
1003 int
1004 main (int argc, char *argv[])
1005 {
1006 mongoc_collection_t *collection;
1007 mongoc_client_t *client;
1008 bson_error_t error;
1009 bson_oid_t oid;
1010 bson_t *doc = NULL;
1011 bson_t *update = NULL;
1012 bson_t *query = NULL;
1013
1014 mongoc_init ();
1015
1016 client =
1017 mongoc_client_new ("mongodb://localhost:27017/?appname=update-example");
1018 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
1019
1020 bson_oid_init (&oid, NULL);
1021 doc = BCON_NEW ("_id", BCON_OID (&oid), "key", BCON_UTF8 ("old_value"));
1022
1023 if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
1024 fprintf (stderr, "%s\n", error.message);
1025 goto fail;
1026 }
1027
1028 query = BCON_NEW ("_id", BCON_OID (&oid));
1029 update = BCON_NEW ("$set",
1030 "{",
1031 "key",
1032 BCON_UTF8 ("new_value"),
1033 "updated",
1034 BCON_BOOL (true),
1035 "}");
1036
1037 if (!mongoc_collection_update_one (
1038 collection, query, update, NULL, NULL, &error)) {
1039 fprintf (stderr, "%s\n", error.message);
1040 goto fail;
1041 }
1042
1043 fail:
1044 if (doc)
1045 bson_destroy (doc);
1046 if (query)
1047 bson_destroy (query);
1048 if (update)
1049 bson_destroy (update);
1050
1051 mongoc_collection_destroy (collection);
1052 mongoc_client_destroy (client);
1053 mongoc_cleanup ();
1054
1055 return 0;
1056 }
1057
1058 Compile the code and run it:
1059
1060 $ gcc -o update update.c $(pkg-config --cflags --libs libmongoc-1.0)
1061 $ ./update
1062
1063 On Windows:
1064
1065 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 update.c
1066 C:\> update
1067 { "_id" : { "$oid" : "55ef43766cb5f36a3bae6ee4" }, "hello" : "world" }
1068
1069 To verify that the update succeeded, connect with the MongoDB shell.
1070
1071 $ mongo
1072 MongoDB shell version: 3.0.6
1073 connecting to: test
1074 > use mydb
1075 switched to db mydb
1076 > db.mycoll.find({"updated" : true})
1077 { "_id" : ObjectId("55ef549236fe322f9490e17b"), "updated" : true, "key" : "new_value" }
1078 >
1079
1080 Deleting a Document
1081 This example illustrates the use of mongoc_collection_delete_one() to
1082 delete a document.
1083
1084 The following code inserts a sample document into the database "mydb"
1085 and collection "mycoll". Then, it deletes all documents matching
1086 {"hello" : "world"}.
1087
1088 #include <bson/bson.h>
1089 #include <mongoc/mongoc.h>
1090 #include <stdio.h>
1091
1092 int
1093 main (int argc, char *argv[])
1094 {
1095 mongoc_client_t *client;
1096 mongoc_collection_t *collection;
1097 bson_error_t error;
1098 bson_oid_t oid;
1099 bson_t *doc;
1100
1101 mongoc_init ();
1102
1103 client =
1104 mongoc_client_new ("mongodb://localhost:27017/?appname=delete-example");
1105 collection = mongoc_client_get_collection (client, "test", "test");
1106
1107 doc = bson_new ();
1108 bson_oid_init (&oid, NULL);
1109 BSON_APPEND_OID (doc, "_id", &oid);
1110 BSON_APPEND_UTF8 (doc, "hello", "world");
1111
1112 if (!mongoc_collection_insert_one (collection, doc, NULL, &error)) {
1113 fprintf (stderr, "Insert failed: %s\n", error.message);
1114 }
1115
1116 bson_destroy (doc);
1117
1118 doc = bson_new ();
1119 BSON_APPEND_OID (doc, "_id", &oid);
1120
1121 if (!mongoc_collection_delete_one (
1122 collection, doc, NULL, NULL, &error)) {
1123 fprintf (stderr, "Delete failed: %s\n", error.message);
1124 }
1125
1126 bson_destroy (doc);
1127 mongoc_collection_destroy (collection);
1128 mongoc_client_destroy (client);
1129 mongoc_cleanup ();
1130
1131 return 0;
1132 }
1133
1134 Compile the code and run it:
1135
1136 $ gcc -o delete delete.c $(pkg-config --cflags --libs libmongoc-1.0)
1137 $ ./delete
1138
1139 On Windows:
1140
1141 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 delete.c
1142 C:\> delete
1143
1144 Use the MongoDB shell to prove that the documents have been removed
1145 successfully.
1146
1147 $ mongo
1148 MongoDB shell version: 3.0.6
1149 connecting to: test
1150 > use mydb
1151 switched to db mydb
1152 > db.mycoll.count({"hello" : "world"})
1153 0
1154 >
1155
1156 Counting Documents
1157 Counting the number of documents in a MongoDB collection is similar to
1158 performing a find operation. This example counts the number of docu‐
1159 ments matching {"hello" : "world"} in the database "mydb" and collec‐
1160 tion "mycoll".
1161
1162 #include <bson/bson.h>
1163 #include <mongoc/mongoc.h>
1164 #include <stdio.h>
1165
1166 int
1167 main (int argc, char *argv[])
1168 {
1169 mongoc_client_t *client;
1170 mongoc_collection_t *collection;
1171 bson_error_t error;
1172 bson_t *doc;
1173 int64_t count;
1174
1175 mongoc_init ();
1176
1177 client =
1178 mongoc_client_new ("mongodb://localhost:27017/?appname=count-example");
1179 collection = mongoc_client_get_collection (client, "mydb", "mycoll");
1180 doc = bson_new_from_json (
1181 (const uint8_t *) "{\"hello\" : \"world\"}", -1, &error);
1182
1183 count = mongoc_collection_count (
1184 collection, MONGOC_QUERY_NONE, doc, 0, 0, NULL, &error);
1185
1186 if (count < 0) {
1187 fprintf (stderr, "%s\n", error.message);
1188 } else {
1189 printf ("%" PRId64 "\n", count);
1190 }
1191
1192 bson_destroy (doc);
1193 mongoc_collection_destroy (collection);
1194 mongoc_client_destroy (client);
1195 mongoc_cleanup ();
1196
1197 return 0;
1198 }
1199
1200 Compile the code and run it:
1201
1202 $ gcc -o count count.c $(pkg-config --cflags --libs libmongoc-1.0)
1203 $ ./count
1204 1
1205
1206 On Windows:
1207
1208 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 count.c
1209 C:\> count
1210 1
1211
1212 Executing Commands
1213 The driver provides helper functions for executing MongoDB commands on
1214 client, database and collection structures. The _simple variants return
1215 booleans indicating success or failure.
1216
1217 This example executes the ping command against the database "mydb".
1218
1219 #include <bson/bson.h>
1220 #include <mongoc/mongoc.h>
1221 #include <stdio.h>
1222
1223 int
1224 main (int argc, char *argv[])
1225 {
1226 mongoc_client_t *client;
1227 bson_error_t error;
1228 bson_t *command;
1229 bson_t reply;
1230 char *str;
1231
1232 mongoc_init ();
1233
1234 client = mongoc_client_new (
1235 "mongodb://localhost:27017/?appname=executing-example");
1236
1237 command = BCON_NEW ("ping", BCON_INT32 (1));
1238 if (mongoc_client_command_simple (
1239 client, "mydb", command, NULL, &reply, &error)) {
1240 str = bson_as_canonical_extended_json (&reply, NULL);
1241 printf ("%s\n", str);
1242 bson_free (str);
1243 } else {
1244 fprintf (stderr, "Failed to run command: %s\n", error.message);
1245 }
1246
1247 bson_destroy (command);
1248 bson_destroy (&reply);
1249 mongoc_client_destroy (client);
1250 mongoc_cleanup ();
1251
1252 return 0;
1253 }
1254
1255
1256 Compile the code and run it:
1257
1258 $ gcc -o executing executing.c $(pkg-config --cflags --libs libmongoc-1.0)
1259 $ ./executing
1260 { "ok" : { "$numberDouble" : "1.0" }, "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } }, "signature" : { "hash" : { "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType" : "00" } }, "keyId" : { "$numberLong" : "0" } } }, "operationTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } } }
1261
1262 On Windows:
1263
1264 C:\> cl.exe /IC:\mongo-c-driver\include\libbson-1.0 /IC:\mongo-c-driver\include\libmongoc-1.0 executing.c
1265 C:\> executing
1266 { "ok" : { "$numberDouble" : "1.0" }, "$clusterTime" : { "clusterTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } }, "signature" : { "hash" : { "$binary" : { "base64" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "subType" : "00" } }, "keyId" : { "$numberLong" : "0" } } }, "operationTime" : { "$timestamp" : { "t" : 1682609211, "i" : 1 } } }
1267
1268 Threading
1269 The MongoDB C Driver is thread-unaware in the vast majority of its op‐
1270 erations. This means it is up to the programmer to guarantee
1271 thread-safety.
1272
1273 However, mongoc_client_pool_t is thread-safe and is used to fetch a
1274 mongoc_client_t in a thread-safe manner. After retrieving a client from
1275 the pool, the client structure should be considered owned by the call‐
1276 ing thread. When the thread is finished, the client should be placed
1277 back into the pool.
1278
1279 example-pool.c
1280
1281 /* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
1282 * libmongoc-1.0) */
1283
1284 /* ./example-pool [CONNECTION_STRING] */
1285
1286 #include <mongoc/mongoc.h>
1287 #include <pthread.h>
1288 #include <stdio.h>
1289
1290 static pthread_mutex_t mutex;
1291 static bool in_shutdown = false;
1292
1293 static void *
1294 worker (void *data)
1295 {
1296 mongoc_client_pool_t *pool = data;
1297 mongoc_client_t *client;
1298 bson_t ping = BSON_INITIALIZER;
1299 bson_error_t error;
1300 bool r;
1301
1302 BSON_APPEND_INT32 (&ping, "ping", 1);
1303
1304 while (true) {
1305 client = mongoc_client_pool_pop (pool);
1306 /* Do something with client. If you are writing an HTTP server, you
1307 * probably only want to hold onto the client for the portion of the
1308 * request performing database queries.
1309 */
1310 r = mongoc_client_command_simple (
1311 client, "admin", &ping, NULL, NULL, &error);
1312
1313 if (!r) {
1314 fprintf (stderr, "%s\n", error.message);
1315 }
1316
1317 mongoc_client_pool_push (pool, client);
1318
1319 pthread_mutex_lock (&mutex);
1320 if (in_shutdown || !r) {
1321 pthread_mutex_unlock (&mutex);
1322 break;
1323 }
1324
1325 pthread_mutex_unlock (&mutex);
1326 }
1327
1328 bson_destroy (&ping);
1329 return NULL;
1330 }
1331
1332 int
1333 main (int argc, char *argv[])
1334 {
1335 const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
1336 mongoc_uri_t *uri;
1337 bson_error_t error;
1338 mongoc_client_pool_t *pool;
1339 pthread_t threads[10];
1340 unsigned i;
1341 void *ret;
1342
1343 pthread_mutex_init (&mutex, NULL);
1344 mongoc_init ();
1345
1346 if (argc > 1) {
1347 uri_string = argv[1];
1348 }
1349
1350 uri = mongoc_uri_new_with_error (uri_string, &error);
1351 if (!uri) {
1352 fprintf (stderr,
1353 "failed to parse URI: %s\n"
1354 "error message: %s\n",
1355 uri_string,
1356 error.message);
1357 return EXIT_FAILURE;
1358 }
1359
1360 pool = mongoc_client_pool_new (uri);
1361 mongoc_client_pool_set_error_api (pool, 2);
1362
1363 for (i = 0; i < 10; i++) {
1364 pthread_create (&threads[i], NULL, worker, pool);
1365 }
1366
1367 sleep (10);
1368 pthread_mutex_lock (&mutex);
1369 in_shutdown = true;
1370 pthread_mutex_unlock (&mutex);
1371
1372 for (i = 0; i < 10; i++) {
1373 pthread_join (threads[i], &ret);
1374 }
1375
1376 mongoc_client_pool_destroy (pool);
1377 mongoc_uri_destroy (uri);
1378
1379 mongoc_cleanup ();
1380
1381 return EXIT_SUCCESS;
1382 }
1383
1384
1385 Next Steps
1386 To find information on advanced topics, browse the rest of the C driver
1387 guide or the official MongoDB documentation.
1388
1389 For help with common issues, consult the Troubleshooting page. To re‐
1390 port a bug or request a new feature, follow these instructions.
1391
1392 Authentication
1393 This guide covers the use of authentication options with the MongoDB C
1394 Driver. Ensure that the MongoDB server is also properly configured for
1395 authentication before making a connection. For more information, see
1396 the MongoDB security documentation.
1397
1398 The MongoDB C driver supports several authentication mechanisms through
1399 the use of MongoDB connection URIs.
1400
1401 By default, if a username and password are provided as part of the con‐
1402 nection string (and an optional authentication database), they are used
1403 to connect via the default authentication mechanism of the server.
1404
1405 To select a specific authentication mechanism other than the default,
1406 see the list of supported mechanism below.
1407
1408 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");
1409
1410 Currently supported values for the authMechanism connection string op‐
1411 tion are:
1412
1413 • SCRAM-SHA-1
1414
1415 • MONGODB-CR (deprecated)
1416
1417 • GSSAPI
1418
1419 • PLAIN
1420
1421 • X509
1422
1423 • MONGODB-AWS
1424
1425 Basic Authentication (SCRAM-SHA-256)
1426 MongoDB 4.0 introduces support for authenticating using the SCRAM pro‐
1427 tocol with the more secure SHA-256 hash described in RFC 7677. Using
1428 this authentication mechanism means that the password is never actually
1429 sent over the wire when authenticating, but rather a computed proof
1430 that the client password is the same as the password the server knows.
1431 In MongoDB 4.0, the C driver can determine the correct default authen‐
1432 tication mechanism for users with stored SCRAM-SHA-1 and SCRAM-SHA-256
1433 credentials:
1434
1435 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authSource=mydb");
1436 /* the correct authMechanism is negotiated between the driver and server. */
1437
1438 Alternatively, SCRAM-SHA-256 can be explicitly specified as an auth‐
1439 Mechanism.
1440
1441 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256&authSource=mydb");
1442
1443 Passwords for SCRAM-SHA-256 undergo the preprocessing step known as
1444 SASLPrep specified in RFC 4013. SASLPrep will only be performed for
1445 passwords containing non-ASCII characters. SASLPrep requires libicu.
1446 If libicu is not available, attempting to authenticate over
1447 SCRAM-SHA-256 with non-ASCII passwords will result in error.
1448
1449 Usernames never undergo SASLPrep.
1450
1451 By default, when building the C driver libicu is linked if available.
1452 This can be changed with the ENABLE_ICU cmake option. To specify an in‐
1453 stallation path of libicu, specify ICU_ROOT as a cmake option. See the
1454 FindICU documentation for more information.
1455
1456 Basic Authentication (SCRAM-SHA-1)
1457 The default authentication mechanism before MongoDB 4.0 is SCRAM-SHA-1
1458 (RFC 5802). Using this authentication mechanism means that the password
1459 is never actually sent over the wire when authenticating, but rather a
1460 computed proof that the client password is the same as the password the
1461 server knows.
1462
1463 mongoc_client_t *client = mongoc_client_new ("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-1&authSource=mydb");
1464
1465 NOTE:
1466 SCRAM-SHA-1 authenticates against the admin database by default. If
1467 the user is created in another database, then specifying the auth‐
1468 Source is required.
1469
1470 Legacy Authentication (MONGODB-CR)
1471 The MONGODB-CR authMechanism is deprecated and will no longer function
1472 in MongoDB 4.0. Instead, specify no authMechanism and the driver will
1473 use an authentication mechanism compatible with your server.
1474
1475 GSSAPI (Kerberos) Authentication
1476 NOTE:
1477 On UNIX-like environments, Kerberos support requires compiling the
1478 driver against cyrus-sasl.
1479
1480 On Windows, Kerberos support requires compiling the driver against
1481 Windows Native SSPI or cyrus-sasl. The default configuration of the
1482 driver will use Windows Native SSPI.
1483
1484 To modify the default configuration, use the cmake option EN‐
1485 ABLE_SASL.
1486
1487 GSSAPI (Kerberos) authentication is available in the Enterprise Edition
1488 of MongoDB. To authenticate using GSSAPI, the MongoDB C driver must be
1489 installed with SASL support.
1490
1491 On UNIX-like environments, run the kinit command before using the fol‐
1492 lowing authentication methods:
1493
1494 $ kinit mongodbuser@EXAMPLE.COM
1495 mongodbuser@EXAMPLE.COM's Password:
1496 $ klistCredentials cache: FILE:/tmp/krb5cc_1000
1497 Principal: mongodbuser@EXAMPLE.COM
1498
1499 Issued Expires Principal
1500 Feb 9 13:48:51 2013 Feb 9 23:48:51 2013 krbtgt/EXAMPLE.COM@EXAMPLE.COM
1501
1502 Now authenticate using the MongoDB URI. GSSAPI authenticates against
1503 the $external virtual database, so a database does not need to be spec‐
1504 ified in the URI. Note that the Kerberos principal must be URL-encoded:
1505
1506 mongoc_client_t *client;
1507
1508 client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI");
1509
1510 NOTE:
1511 GSSAPI authenticates against the $external database, so specifying
1512 the authSource database is not required.
1513
1514 The driver supports these GSSAPI properties:
1515
1516 • CANONICALIZE_HOST_NAME: This might be required with Cyrus-SASL when
1517 the hosts report different hostnames than what is used in the Ker‐
1518 beros database. The default is "false".
1519
1520 • SERVICE_NAME: Use a different service name than the default, "mon‐
1521 godb".
1522
1523 Set properties in the URL:
1524
1525 mongoc_client_t *client;
1526
1527 client = mongoc_client_new ("mongodb://mongodbuser%40EXAMPLE.COM@mongo-server.example.com/?authMechanism=GSSAPI&"
1528 "authMechanismProperties=SERVICE_NAME:other,CANONICALIZE_HOST_NAME:true");
1529
1530 If you encounter errors such as Invalid net address, check if the ap‐
1531 plication is behind a NAT (Network Address Translation) firewall. If
1532 so, create a ticket that uses forwardable and addressless Kerberos
1533 tickets. This can be done by passing -f -A to kinit.
1534
1535 $ kinit -f -A mongodbuser@EXAMPLE.COM
1536
1537 SASL Plain Authentication
1538 NOTE:
1539 The MongoDB C Driver must be compiled with SASL support in order to
1540 use SASL PLAIN authentication.
1541
1542 MongoDB Enterprise Edition supports the SASL PLAIN authentication mech‐
1543 anism, initially intended for delegating authentication to an LDAP
1544 server. Using the SASL PLAIN mechanism is very similar to the challenge
1545 response mechanism with usernames and passwords. This authentication
1546 mechanism uses the $external virtual database for LDAP support:
1547
1548 NOTE:
1549 SASL PLAIN is a clear-text authentication mechanism. It is strongly
1550 recommended to connect to MongoDB using TLS with certificate valida‐
1551 tion when using the PLAIN mechanism.
1552
1553 mongoc_client_t *client;
1554
1555 client = mongoc_client_new ("mongodb://user:password@example.com/?authMechanism=PLAIN");
1556
1557 PLAIN authenticates against the $external database, so specifying the
1558 authSource database is not required.
1559
1560 X.509 Certificate Authentication
1561 NOTE:
1562 The MongoDB C Driver must be compiled with TLS support for X.509 au‐
1563 thentication support. Once this is done, start a server with the
1564 following options:
1565
1566 $ mongod --tlsMode requireTLS --tlsCertificateKeyFile server.pem --tlsCAFile ca.pem
1567
1568 The MONGODB-X509 mechanism authenticates a username derived from the
1569 distinguished subject name of the X.509 certificate presented by the
1570 driver during TLS negotiation. This authentication method requires the
1571 use of TLS connections with certificate validation.
1572
1573 mongoc_client_t *client;
1574 mongoc_ssl_opt_t ssl_opts = { 0 };
1575
1576 ssl_opts.pem_file = "mycert.pem";
1577 ssl_opts.pem_pwd = "mycertpassword";
1578 ssl_opts.ca_file = "myca.pem";
1579 ssl_opts.ca_dir = "trust_dir";
1580 ssl_opts.weak_cert_validation = false;
1581
1582 client = mongoc_client_new ("mongodb://x509_derived_username@localhost/?authMechanism=MONGODB-X509");
1583 mongoc_client_set_ssl_opts (client, &ssl_opts);
1584
1585 MONGODB-X509 authenticates against the $external database, so specify‐
1586 ing the authSource database is not required. For more information on
1587 the x509_derived_username, see the MongoDB server x.509 tutorial.
1588
1589 NOTE:
1590 The MongoDB C Driver will attempt to determine the x509 derived
1591 username when none is provided, and as of MongoDB 3.4 providing the
1592 username is not required at all.
1593
1594 Authentication via AWS IAM
1595 The MONGODB-AWS mechanism authenticates to MongoDB servers with creden‐
1596 tials provided by AWS Identity and Access Management (IAM).
1597
1598 To authenticate, create a user with an associated Amazon Resource Name
1599 (ARN) on the $external database, and specify the MONGODB-AWS authMecha‐
1600 nism in the URI.
1601
1602 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost/?authMechanism=MONGODB-AWS");
1603
1604 Since MONGODB-AWS always authenticates against the $external database,
1605 so specifying the authSource database is not required.
1606
1607 Credentials include the access key id, secret access key, and optional
1608 session token. They may be obtained from the following ways.
1609
1610 AWS credentials via URI
1611 Credentials may be passed directly in the URI as username/password.
1612
1613 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://<access key id>:<secret access key>localhost/?authMechanism=MONGODB-AWS");
1614
1615 This may include a session token passed with authMechanismProperties.
1616
1617 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://<access key id>:<secret access key>localhost/?authMechanism=MONGODB-AWS&authMechanismProperties=AWS_SESSION_TOKEN:<token>");
1618
1619 AWS credentials via environment
1620 If credentials are not passed through the URI, libmongoc will check for
1621 the following environment variables.
1622
1623 • AWS_ACCESS_KEY_ID
1624
1625 • AWS_SECRET_ACCESS_KEY
1626
1627 • AWS_SESSION_TOKEN (optional)
1628
1629 AWS Credentials via ECS
1630 If credentials are not passed in the URI or with environment variables,
1631 libmongoc will check if the environment variable AWS_CONTAINER_CREDEN‐
1632 TIALS_RELATIVE_URI is set, and if so, attempt to retrieve temporary
1633 credentials from the ECS task metadata by querying a link local ad‐
1634 dress.
1635
1636 AWS Credentials via EC2
1637 If credentials are not passed in the URI or with environment variables,
1638 and the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is
1639 not set, libmongoc will attempt to retrieve temporary credentials from
1640 the EC2 machine metadata by querying link local addresses.
1641
1642 Basic Troubleshooting
1643 Troubleshooting Checklist
1644 The following is a short list of things to check when you have a prob‐
1645 lem.
1646
1647 • Did you call mongoc_init() in main()? If not, you will likely see a
1648 segfault.
1649
1650 • Have you leaked any clients or cursors as can be found with mon‐
1651 goc-stat <PID>?
1652
1653 • Have packets been delivered to the server? See egress bytes from mon‐
1654 goc-stat <PID>.
1655
1656 • Does ASAN show any leaks? Ensure you call mongoc_cleanup() at the end
1657 of your process to cleanup lingering allocations from the MongoDB C
1658 driver.
1659
1660 • If compiling your own copy of MongoDB C Driver, consider using the
1661 cmake option -DENABLE_TRACING=ON to enable function tracing and hex
1662 dumps of network packets to STDERR and STDOUT.
1663
1664 Performance Counters
1665 The MongoDB C Driver comes with an optional and unique feature to help
1666 developers and sysadmins troubleshoot problems in production. Perfor‐
1667 mance counters are available for each process using the C Driver. If
1668 available, the counters can be accessed outside of the application
1669 process via a shared memory segment. The counters may be used graph
1670 statistics about your application process easily from tools like Munin
1671 or Nagios. For example, the command watch --interval=0.5 -d mon‐
1672 goc-stat $PID may be used to monitor an application.
1673
1674 Performance counters are only available on Linux platforms and macOS
1675 arm64 platforms that support shared memory segments. On supported
1676 platforms, they are enabled by default. Applications can be built
1677 without the counters by specifying the cmake option -DENABLE_SHM_COUN‐
1678 TERS=OFF. Additionally, if performance counters are already compiled,
1679 they can be disabled at runtime by specifying the environment variable
1680 MONGOC_DISABLE_SHM.
1681
1682 Performance counters keep track of the following:
1683
1684 • Active and Disposed Cursors
1685
1686 • Active and Disposed Clients, Client Pools, and Socket Streams.
1687
1688 • Number of operations sent and received, by type.
1689
1690 • Bytes transferred and received.
1691
1692 • Authentication successes and failures.
1693
1694 • Number of wire protocol errors.
1695
1696 NOTE:
1697 An operation is considered "sent" when one or more bytes of the cor‐
1698 responding message is written to the stream, regardless of whether
1699 the entire message is successfully written or if the operation ulti‐
1700 mately succeeds or fails. This does not include bytes that may be
1701 written during the stream connection process, such as TLS handshake
1702 messages.
1703
1704 To access counters for a given process, simply provide the process id
1705 to the mongoc-stat program installed with the MongoDB C Driver.
1706
1707 $ mongoc-stat 22203
1708 Operations : Egress Total : The number of sent operations. : 13247
1709 Operations : Ingress Total : The number of received operations. : 13246
1710 Operations : Egress Queries : The number of sent Query operations. : 13247
1711 Operations : Ingress Queries : The number of received Query operations. : 0
1712 Operations : Egress GetMore : The number of sent GetMore operations. : 0
1713 Operations : Ingress GetMore : The number of received GetMore operations. : 0
1714 Operations : Egress Insert : The number of sent Insert operations. : 0
1715 Operations : Ingress Insert : The number of received Insert operations. : 0
1716 Operations : Egress Delete : The number of sent Delete operations. : 0
1717 Operations : Ingress Delete : The number of received Delete operations. : 0
1718 Operations : Egress Update : The number of sent Update operations. : 0
1719 Operations : Ingress Update : The number of received Update operations. : 0
1720 Operations : Egress KillCursors : The number of sent KillCursors operations. : 0
1721 Operations : Ingress KillCursors : The number of received KillCursors operations. : 0
1722 Operations : Egress Msg : The number of sent Msg operations. : 0
1723 Operations : Ingress Msg : The number of received Msg operations. : 0
1724 Operations : Egress Reply : The number of sent Reply operations. : 0
1725 Operations : Ingress Reply : The number of received Reply operations. : 13246
1726 Cursors : Active : The number of active cursors. : 1
1727 Cursors : Disposed : The number of disposed cursors. : 13246
1728 Clients : Active : The number of active clients. : 1
1729 Clients : Disposed : The number of disposed clients. : 0
1730 Streams : Active : The number of active streams. : 1
1731 Streams : Disposed : The number of disposed streams. : 0
1732 Streams : Egress Bytes : The number of bytes sent. : 794931
1733 Streams : Ingress Bytes : The number of bytes received. : 589694
1734 Streams : N Socket Timeouts : The number of socket timeouts. : 0
1735 Client Pools : Active : The number of active client pools. : 1
1736 Client Pools : Disposed : The number of disposed client pools. : 0
1737 Protocol : Ingress Errors : The number of protocol errors on ingress. : 0
1738 Auth : Failures : The number of failed authentication requests. : 0
1739 Auth : Success : The number of successful authentication requests. : 0
1740
1741 Submitting a Bug Report
1742 Think you've found a bug? Want to see a new feature in the MongoDB C
1743 driver? Please open a case in our issue management tool, JIRA:
1744
1745 • Create an account and login.
1746
1747 • Navigate to the CDRIVER project.
1748
1749 • Click Create Issue - Please provide as much information as possible
1750 about the issue type and how to reproduce it.
1751
1752 Bug reports in JIRA for all driver projects (i.e. CDRIVER, CSHARP,
1753 JAVA) and the Core Server (i.e. SERVER) project are public.
1754
1755 Guides
1756 Configuring TLS
1757 Configuration with URI options
1758 Enable TLS by including tls=true in the URI.
1759
1760 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/");
1761 mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true);
1762
1763 mongoc_client_t *client = mongoc_client_new_from_uri (uri);
1764
1765 The following URI options may be used to further configure TLS:
1766
1767 ┌────────────────────┬─────────────────────┬─────────────────────┐
1768 │Constant │ Key │ Description │
1769 ├────────────────────┼─────────────────────┼─────────────────────┤
1770 │MONGOC_URI_TLS │ tls │ {true|false}, indi‐ │
1771 │ │ │ cating if TLS must │
1772 │ │ │ be used. │
1773 ├────────────────────┼─────────────────────┼─────────────────────┤
1774 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ Path to PEM format‐ │
1775 │TIFICATEKEYFILE │ file │ ted Private Key, │
1776 │ │ │ with its Public │
1777 │ │ │ Certificate con‐ │
1778 │ │ │ catenated at the │
1779 │ │ │ end. │
1780 ├────────────────────┼─────────────────────┼─────────────────────┤
1781 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ The password, if │
1782 │TIFICATEKEY‐ │ password │ any, to use to un‐ │
1783 │FILEPASSWORD │ │ lock encrypted Pri‐ │
1784 │ │ │ vate Key. │
1785 └────────────────────┴─────────────────────┴─────────────────────┘
1786
1787
1788
1789
1790 │MON‐ │ tlscafile │ One, or a bundle │
1791 │GOC_URI_TLSCAFILE │ │ of, Certificate Au‐ │
1792 │ │ │ thorities whom │
1793 │ │ │ should be consid‐ │
1794 │ │ │ ered to be trusted. │
1795 ├────────────────────┼─────────────────────┼─────────────────────┤
1796 │MONGOC_URI_TLSAL‐ │ tlsallowinvalidcer‐ │ Accept and ignore │
1797 │LOWINVALIDCERTIFI‐ │ tificates │ certificate verifi‐ │
1798 │CATES │ │ cation errors (e.g. │
1799 │ │ │ untrusted issuer, │
1800 │ │ │ expired, etc.) │
1801 ├────────────────────┼─────────────────────┼─────────────────────┤
1802 │MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │ Ignore hostname │
1803 │LOWINVALIDHOSTNAMES │ hostnames │ verification of the │
1804 │ │ │ certificate (e.g. │
1805 │ │ │ Man In The Middle, │
1806 │ │ │ using valid cer‐ │
1807 │ │ │ tificate, but is‐ │
1808 │ │ │ sued for another │
1809 │ │ │ hostname) │
1810 ├────────────────────┼─────────────────────┼─────────────────────┤
1811 │MONGOC_URI_TLSINSE‐ │ tlsinsecure │ {true|false}, indi‐ │
1812 │CURE │ │ cating if insecure │
1813 │ │ │ TLS options should │
1814 │ │ │ be used. Currently │
1815 │ │ │ this implies MON‐ │
1816 │ │ │ GOC_URI_TLSALLOWIN‐ │
1817 │ │ │ VALIDCERTIFICATES │
1818 │ │ │ and MONGOC_URI_TL‐ │
1819 │ │ │ SALLOWINVALIDHOST‐ │
1820 │ │ │ NAMES. │
1821 ├────────────────────┼─────────────────────┼─────────────────────┤
1822 │MONGOC_URI_TLSDIS‐ │ tlsdisablecertifi‐ │ {true|false}, indi‐ │
1823 │ABLECERTIFICATERE‐ │ caterevocationcheck │ cates if revocation │
1824 │VOCATIONCHECK │ │ checking (CRL / │
1825 │ │ │ OCSP) should be │
1826 │ │ │ disabled. │
1827 ├────────────────────┼─────────────────────┼─────────────────────┤
1828 │MONGOC_URI_TLSDIS‐ │ tlsdisableocspend‐ │ {true|false}, indi‐ │
1829 │ABLEOCSPEND‐ │ pointcheck │ cates if OCSP re‐ │
1830 │POINTCHECK │ │ sponder endpoints │
1831 │ │ │ should not be re‐ │
1832 │ │ │ quested when an │
1833 │ │ │ OCSP response is │
1834 │ │ │ not stapled. │
1835 └────────────────────┴─────────────────────┴─────────────────────┘
1836
1837 Configuration with mongoc_ssl_opt_t
1838 Alternatively, the mongoc_ssl_opt_t struct may be used to configure TLS
1839 with mongoc_client_set_ssl_opts() or mongoc_client_pool_set_ssl_opts().
1840 Most of the configurable options can be set using the Connection String
1841 URI.
1842
1843 ┌───────────────────────┬──────────────────────────┐
1844 │mongoc_ssl_opt_t key │ URI key │
1845 ├───────────────────────┼──────────────────────────┤
1846 │pem_file │ tlsClientCertificateKey‐ │
1847 │ │ File │
1848 ├───────────────────────┼──────────────────────────┤
1849 │pem_pwd │ tlsClientCertificateKey‐ │
1850 │ │ Password │
1851 ├───────────────────────┼──────────────────────────┤
1852 │ca_file │ tlsCAFile │
1853 └───────────────────────┴──────────────────────────┘
1854
1855
1856
1857 │weak_cert_validation │ tlsAllowInvalidCertifi‐ │
1858 │ │ cates │
1859 ├───────────────────────┼──────────────────────────┤
1860 │allow_invalid_hostname │ tlsAllowInvalidHostnames │
1861 └───────────────────────┴──────────────────────────┘
1862
1863 The only exclusions are crl_file and ca_dir. Those may only be set with
1864 mongoc_ssl_opt_t.
1865
1866 Client Authentication
1867 When MongoDB is started with TLS enabled, it will by default require
1868 the client to provide a client certificate issued by a certificate au‐
1869 thority specified by --tlsCAFile, or an authority trusted by the native
1870 certificate store in use on the server.
1871
1872 To provide the client certificate, set the tlsCertificateKeyFile in the
1873 URI to a PEM armored certificate file.
1874
1875 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/");
1876 mongoc_uri_set_option_as_bool (uri, MONGOC_URI_TLS, true);
1877 mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "/path/to/client-certificate.pem");
1878
1879 mongoc_client_t *client = mongoc_client_new_from_uri (uri);
1880
1881 Server Certificate Verification
1882 The MongoDB C Driver will automatically verify the validity of the
1883 server certificate, such as issued by configured Certificate Authority,
1884 hostname validation, and expiration.
1885
1886 To overwrite this behavior, it is possible to disable hostname valida‐
1887 tion, OCSP endpoint revocation checking, revocation checking entirely,
1888 and allow invalid certificates.
1889
1890 This behavior is controlled using the tlsAllowInvalidHostnames, tlsDis‐
1891 ableOCSPEndpointCheck, tlsDisableCertificateRevocationCheck, and tlsAl‐
1892 lowInvalidCertificates options respectively. By default, all are set to
1893 false.
1894
1895 It is not recommended to change these defaults as it exposes the client
1896 to Man In The Middle attacks (when tlsAllowInvalidHostnames is set),
1897 invalid certificates (when tlsAllowInvalidCertificates is set), or po‐
1898 tentially revoked certificates (when tlsDisableOCSPEndpointCheck or
1899 tlsDisableCertificateRevocationCheck are set).
1900
1901 Supported Libraries
1902 By default, libmongoc will attempt to find a supported TLS library and
1903 enable TLS support. This is controlled by the cmake flag ENABLE_SSL,
1904 which is set to AUTO by default. Valid values are:
1905
1906 • AUTO the default behavior. Link to the system's native TLS library,
1907 or attempt to find OpenSSL.
1908
1909 • DARWIN link to Secure Transport, the native TLS library on macOS.
1910
1911 • WINDOWS link to Secure Channel, the native TLS library on Windows.
1912
1913 • OPENSSL link to OpenSSL (libssl). An optional install path may be
1914 specified with OPENSSL_ROOT.
1915
1916 • LIBRESSL link to LibreSSL's libtls. (LibreSSL's compatible libssl may
1917 be linked to by setting OPENSSL).
1918
1919 • OFF disable TLS support.
1920
1921 OpenSSL
1922 The MongoDB C Driver uses OpenSSL, if available, on Linux and Unix
1923 platforms (besides macOS). Industry best practices and some regulations
1924 require the use of TLS 1.1 or newer, which requires at least OpenSSL
1925 1.0.1. Check your OpenSSL version like so:
1926
1927 $ openssl version
1928
1929 Ensure your system's OpenSSL is a recent version (at least 1.0.1), or
1930 install a recent version in a non-system path and build against it
1931 with:
1932
1933 cmake -DOPENSSL_ROOT_DIR=/absolute/path/to/openssl
1934
1935 When compiled against OpenSSL, the driver will attempt to load the sys‐
1936 tem default certificate store, as configured by the distribution. That
1937 can be overridden by setting the tlsCAFile URI option or with the
1938 fields ca_file and ca_dir in the mongoc_ssl_opt_t.
1939
1940 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is fully
1941 supported when using OpenSSL 1.0.1+ with the following notes:
1942
1943 • When a crl_file is set with mongoc_ssl_opt_t, and the crl_file re‐
1944 vokes the server's certificate, the certificate is considered revoked
1945 (even if the certificate has a valid stapled OCSP response)
1946
1947 LibreSSL / libtls
1948 The MongoDB C Driver supports LibreSSL through the use of OpenSSL com‐
1949 patibility checks when configured to compile against openssl. It also
1950 supports the new libtls library when configured to build against li‐
1951 bressl.
1952
1953 When compiled against the Windows native libraries, the crl_file option
1954 of a mongoc_ssl_opt_t is not supported, and will issue an error if
1955 used.
1956
1957 Setting tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevoca‐
1958 tionCheck has no effect.
1959
1960 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
1961 tially supported with the following notes:
1962
1963 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
1964 continue if a Must-Staple certificate is presented with no stapled
1965 response (unless the client receives a revoked response from an OCSP
1966 responder).
1967
1968 • Connection will continue if a Must-Staple certificate is presented
1969 without a stapled response and the OCSP responder is down.
1970
1971 Native TLS Support on Windows (Secure Channel)
1972 The MongoDB C Driver supports the Windows native TLS library (Secure
1973 Channel, or SChannel), and its native crypto library (Cryptography API:
1974 Next Generation, or CNG).
1975
1976 When compiled against the Windows native libraries, the ca_dir option
1977 of a mongoc_ssl_opt_t is not supported, and will issue an error if
1978 used.
1979
1980 Encrypted PEM files (e.g., setting tlsCertificateKeyPassword) are also
1981 not supported, and will result in error when attempting to load them.
1982
1983 When tlsCAFile is set, the driver will only allow server certificates
1984 issued by the authority (or authorities) provided. When no tlsCAFile is
1985 set, the driver will look up the Certificate Authority using the System
1986 Local Machine Root certificate store to confirm the provided certifi‐
1987 cate.
1988
1989 When crl_file is set with mongoc_ssl_opt_t, the driver will import the
1990 revocation list to the System Local Machine Root certificate store.
1991
1992 Setting tlsDisableOCSPEndpointCheck has no effect.
1993
1994 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
1995 tially supported with the following notes:
1996
1997 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
1998 continue if a Must-Staple certificate is presented with no stapled
1999 response (unless the client receives a revoked response from an OCSP
2000 responder).
2001
2002 • When a crl_file is set with mongoc_ssl_opt_t, and the crl_file re‐
2003 vokes the server's certificate, the OCSP response takes precedence.
2004 E.g. if the server presents a certificate with a valid stapled OCSP
2005 response, the certificate is considered valid even if the crl_file
2006 marks it as revoked.
2007
2008 • Connection will continue if a Must-Staple certificate is presented
2009 without a stapled response and the OCSP responder is down.
2010
2011 Native TLS Support on macOS / Darwin (Secure Transport)
2012 The MongoDB C Driver supports the Darwin (OS X, macOS, iOS, etc.) na‐
2013 tive TLS library (Secure Transport), and its native crypto library
2014 (Common Crypto, or CC).
2015
2016 When compiled against Secure Transport, the ca_dir and crl_file options
2017 of a mongoc_ssl_opt_t are not supported. An error is issued if either
2018 are used.
2019
2020 When tlsCAFile is set, the driver will only allow server certificates
2021 issued by the authority (or authorities) provided. When no tlsCAFile is
2022 set, the driver will use the Certificate Authorities in the currently
2023 unlocked keychains.
2024
2025 Setting tlsDisableOCSPEndpointCheck and tlsDisableCertificateRevoca‐
2026 tionCheck has no effect.
2027
2028 The Online Certificate Status Protocol (OCSP) (see RFC 6960) is par‐
2029 tially supported with the following notes.
2030
2031 • The Must-Staple extension (see RFC 7633) is ignored. Connection may
2032 continue if a Must-Staple certificate is presented with no stapled
2033 response (unless the client receives a revoked response from an OCSP
2034 responder).
2035
2036 • Connection will continue if a Must-Staple certificate is presented
2037 without a stapled response and the OCSP responder is down.
2038
2039 Common Tasks
2040 Drivers for some other languages provide helper functions to perform
2041 certain common tasks. In the C Driver we must explicitly build commands
2042 to send to the server.
2043
2044 Setup
2045 First we'll write some code to insert sample data:
2046
2047 doc-common-insert.c
2048
2049 /* Don't try to compile this file on its own. It's meant to be #included
2050 by example code */
2051
2052 /* Insert some sample data */
2053 bool
2054 insert_data (mongoc_collection_t *collection)
2055 {
2056 mongoc_bulk_operation_t *bulk;
2057 enum N { ndocs = 4 };
2058 bson_t *docs[ndocs];
2059 bson_error_t error;
2060 int i = 0;
2061 bool ret;
2062
2063 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2064
2065 docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
2066 docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
2067 docs[2] = BCON_NEW (
2068 "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
2069 docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");
2070
2071 for (i = 0; i < ndocs; i++) {
2072 mongoc_bulk_operation_insert (bulk, docs[i]);
2073 bson_destroy (docs[i]);
2074 docs[i] = NULL;
2075 }
2076
2077 ret = mongoc_bulk_operation_execute (bulk, NULL, &error);
2078
2079 if (!ret) {
2080 fprintf (stderr, "Error inserting data: %s\n", error.message);
2081 }
2082
2083 mongoc_bulk_operation_destroy (bulk);
2084 return ret;
2085 }
2086
2087 /* A helper which we'll use a lot later on */
2088 void
2089 print_res (const bson_t *reply)
2090 {
2091 char *str;
2092 BSON_ASSERT (reply);
2093 str = bson_as_canonical_extended_json (reply, NULL);
2094 printf ("%s\n", str);
2095 bson_free (str);
2096 }
2097
2098
2099 "explain" Command
2100 This is how to use the explain command in MongoDB 3.2+:
2101
2102 explain.c
2103
2104 bool
2105 explain (mongoc_collection_t *collection)
2106 {
2107 bson_t *command;
2108 bson_t reply;
2109 bson_error_t error;
2110 bool res;
2111
2112 command = BCON_NEW ("explain",
2113 "{",
2114 "find",
2115 BCON_UTF8 (COLLECTION_NAME),
2116 "filter",
2117 "{",
2118 "x",
2119 BCON_INT32 (1),
2120 "}",
2121 "}");
2122 res = mongoc_collection_command_simple (
2123 collection, command, NULL, &reply, &error);
2124 if (!res) {
2125 fprintf (stderr, "Error with explain: %s\n", error.message);
2126 goto cleanup;
2127 }
2128
2129 /* Do something with the reply */
2130 print_res (&reply);
2131
2132 cleanup:
2133 bson_destroy (&reply);
2134 bson_destroy (command);
2135 return res;
2136 }
2137
2138
2139 Running the Examples
2140 common-operations.c
2141
2142 /*
2143 * Copyright 2016 MongoDB, Inc.
2144 *
2145 * Licensed under the Apache License, Version 2.0 (the "License");
2146 * you may not use this file except in compliance with the License.
2147 * You may obtain a copy of the License at
2148 *
2149 * http://www.apache.org/licenses/LICENSE-2.0
2150 *
2151 * Unless required by applicable law or agreed to in writing, software
2152 * distributed under the License is distributed on an "AS IS" BASIS,
2153 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2154 * See the License for the specific language governing permissions and
2155 * limitations under the License.
2156 */
2157
2158
2159 #include <mongoc/mongoc.h>
2160 #include <stdio.h>
2161
2162
2163 const char *COLLECTION_NAME = "things";
2164
2165 #include "../doc-common-insert.c"
2166 #include "explain.c"
2167
2168
2169 int
2170 main (int argc, char *argv[])
2171 {
2172 mongoc_database_t *database = NULL;
2173 mongoc_client_t *client = NULL;
2174 mongoc_collection_t *collection = NULL;
2175 mongoc_uri_t *uri = NULL;
2176 bson_error_t error;
2177 char *host_and_port;
2178 int res = 0;
2179
2180 if (argc < 2 || argc > 3) {
2181 fprintf (stderr,
2182 "usage: %s MONGOD-1-CONNECTION-STRING "
2183 "[MONGOD-2-HOST-NAME:MONGOD-2-PORT]\n",
2184 argv[0]);
2185 fprintf (stderr,
2186 "MONGOD-1-CONNECTION-STRING can be "
2187 "of the following forms:\n");
2188 fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
2189 fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
2190 fprintf (stderr,
2191 "mongodb://user:pass@localhost:27017\t"
2192 "local machine on port 27017, and authenticate with username "
2193 "user and password pass\n");
2194 return EXIT_FAILURE;
2195 }
2196
2197 mongoc_init ();
2198
2199 if (strncmp (argv[1], "mongodb://", 10) == 0) {
2200 host_and_port = bson_strdup (argv[1]);
2201 } else {
2202 host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
2203 }
2204
2205 uri = mongoc_uri_new_with_error (host_and_port, &error);
2206 if (!uri) {
2207 fprintf (stderr,
2208 "failed to parse URI: %s\n"
2209 "error message: %s\n",
2210 host_and_port,
2211 error.message);
2212 res = EXIT_FAILURE;
2213 goto cleanup;
2214 }
2215
2216 client = mongoc_client_new_from_uri (uri);
2217 if (!client) {
2218 res = EXIT_FAILURE;
2219 goto cleanup;
2220 }
2221
2222 mongoc_client_set_error_api (client, 2);
2223 database = mongoc_client_get_database (client, "test");
2224 collection = mongoc_database_get_collection (database, COLLECTION_NAME);
2225
2226 printf ("Inserting data\n");
2227 if (!insert_data (collection)) {
2228 res = EXIT_FAILURE;
2229 goto cleanup;
2230 }
2231
2232 printf ("explain\n");
2233 if (!explain (collection)) {
2234 res = EXIT_FAILURE;
2235 goto cleanup;
2236 }
2237
2238 cleanup:
2239 if (collection) {
2240 mongoc_collection_destroy (collection);
2241 }
2242
2243 if (database) {
2244 mongoc_database_destroy (database);
2245 }
2246
2247 if (client) {
2248 mongoc_client_destroy (client);
2249 }
2250
2251 if (uri) {
2252 mongoc_uri_destroy (uri);
2253 }
2254
2255 bson_free (host_and_port);
2256 mongoc_cleanup ();
2257 return res;
2258 }
2259
2260
2261 First launch two separate instances of mongod (must be done from sepa‐
2262 rate shells):
2263
2264 $ mongod
2265
2266 $ mkdir /tmp/db2
2267 $ mongod --dbpath /tmp/db2 --port 27018 # second instance
2268
2269 Now compile and run the example program:
2270
2271 $ cd examples/common_operations/$ gcc -Wall -o example common-operations.c $(pkg-config --cflags --libs libmongoc-1.0)$ ./example localhost:27017 localhost:27018
2272 Inserting data
2273 explain
2274 {
2275 "executionStats" : {
2276 "allPlansExecution" : [],
2277 "executionStages" : {
2278 "advanced" : 19,
2279 "direction" : "forward" ,
2280 "docsExamined" : 76,
2281 "executionTimeMillisEstimate" : 0,
2282 "filter" : {
2283 "x" : {
2284 "$eq" : 1
2285 }
2286 },
2287 "invalidates" : 0,
2288 "isEOF" : 1,
2289 "nReturned" : 19,
2290 "needTime" : 58,
2291 "needYield" : 0,
2292 "restoreState" : 0,
2293 "saveState" : 0,
2294 "stage" : "COLLSCAN" ,
2295 "works" : 78
2296 },
2297 "executionSuccess" : true,
2298 "executionTimeMillis" : 0,
2299 "nReturned" : 19,
2300 "totalDocsExamined" : 76,
2301 "totalKeysExamined" : 0
2302 },
2303 "ok" : 1,
2304 "queryPlanner" : {
2305 "indexFilterSet" : false,
2306 "namespace" : "test.things",
2307 "parsedQuery" : {
2308 "x" : {
2309 "$eq" : 1
2310 }
2311 },
2312 "plannerVersion" : 1,
2313 "rejectedPlans" : [],
2314 "winningPlan" : {
2315 "direction" : "forward" ,
2316 "filter" : {
2317 "x" : {
2318 "$eq" : 1
2319 }
2320 },
2321 "stage" : "COLLSCAN"
2322 }
2323 },
2324 "serverInfo" : {
2325 "gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25" ,
2326 "host" : "MacBook-Pro-57.local",
2327 "port" : 27017,
2328 "version" : "3.2.6"
2329 }
2330 }
2331
2332 Advanced Connections
2333 The following guide contains information specific to certain types of
2334 MongoDB configurations.
2335
2336 For an example of connecting to a simple standalone server, see the
2337 Tutorial. To establish a connection with authentication options en‐
2338 abled, see the Authentication page.
2339
2340 Connecting to a Replica Set
2341 Connecting to a replica set is much like connecting to a standalone
2342 MongoDB server. Simply specify the replica set name using the ?repli‐
2343 caSet=myreplset URI option.
2344
2345 #include <bson/bson.h>
2346 #include <mongoc/mongoc.h>
2347
2348 int
2349 main (int argc, char *argv[])
2350 {
2351 mongoc_client_t *client;
2352
2353 mongoc_init ();
2354
2355 /* Create our MongoDB Client */
2356 client = mongoc_client_new (
2357 "mongodb://host01:27017,host02:27017,host03:27017/?replicaSet=myreplset");
2358
2359 /* Do some work */
2360 /* TODO */
2361
2362 /* Clean up */
2363 mongoc_client_destroy (client);
2364 mongoc_cleanup ();
2365
2366 return 0;
2367 }
2368
2369 TIP:
2370 Multiple hostnames can be specified in the MongoDB connection string
2371 URI, with a comma separating hosts in the seed list.
2372
2373 It is recommended to use a seed list of members of the replica set
2374 to allow the driver to connect to any node.
2375
2376 Connecting to a Sharded Cluster
2377 To connect to a sharded cluster, specify the mongos nodes the client
2378 should connect to. The C Driver will automatically detect that it has
2379 connected to a mongos sharding server.
2380
2381 If more than one hostname is specified, a seed list will be created to
2382 attempt failover between the mongos instances.
2383
2384 WARNING:
2385 Specifying the replicaSet parameter when connecting to a mongos
2386 sharding server is invalid.
2387
2388 #include <bson/bson.h>
2389 #include <mongoc/mongoc.h>
2390
2391 int
2392 main (int argc, char *argv[])
2393 {
2394 mongoc_client_t *client;
2395
2396 mongoc_init ();
2397
2398 /* Create our MongoDB Client */
2399 client = mongoc_client_new ("mongodb://myshard01:27017/");
2400
2401 /* Do something with client ... */
2402
2403 /* Free the client */
2404 mongoc_client_destroy (client);
2405
2406 mongoc_cleanup ();
2407
2408 return 0;
2409 }
2410
2411 Connecting to an IPv6 Address
2412 The MongoDB C Driver will automatically resolve IPv6 addresses from
2413 host names. However, to specify an IPv6 address directly, wrap the ad‐
2414 dress in [].
2415
2416 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://[::1]:27017");
2417
2418 Connecting with IPv4 and IPv6
2419 If connecting to a hostname that has both IPv4 and IPv6 DNS records,
2420 the behavior follows RFC-6555. A connection to the IPv6 address is at‐
2421 tempted first. If IPv6 fails, then a connection is attempted to the
2422 IPv4 address. If the connection attempt to IPv6 does not complete
2423 within 250ms, then IPv4 is tried in parallel. Whichever succeeds con‐
2424 nection first cancels the other. The successful DNS result is cached
2425 for 10 minutes.
2426
2427 As a consequence, attempts to connect to a mongod only listening on
2428 IPv4 may be delayed if there are both A (IPv4) and AAAA (IPv6) DNS
2429 records associated with the host.
2430
2431 To avoid a delay, configure hostnames to match the MongoDB configura‐
2432 tion. That is, only create an A record if the mongod is only listening
2433 on IPv4.
2434
2435 Connecting to a UNIX Domain Socket
2436 On UNIX-like systems, the C Driver can connect directly to a MongoDB
2437 server using a UNIX domain socket. Pass the URL-encoded path to the
2438 socket, which must be suffixed with .sock. For example, to connect to a
2439 domain socket at /tmp/mongodb-27017.sock:
2440
2441 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://%2Ftmp%2Fmongodb-27017.sock");
2442
2443 Include username and password like so:
2444
2445 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://user:pass@%2Ftmp%2Fmongodb-27017.sock");
2446
2447 Connecting to a server over TLS
2448 These are instructions for configuring TLS/SSL connections.
2449
2450 To run a server locally (on port 27017, for example):
2451
2452 $ mongod --port 27017 --tlsMode requireTLS --tlsCertificateKeyFile server.pem --tlsCAFile ca.pem
2453
2454 Add /?tls=true to the end of a client URI.
2455
2456 mongoc_client_t *client = NULL;
2457 client = mongoc_client_new ("mongodb://localhost:27017/?tls=true");
2458
2459 MongoDB requires client certificates by default, unless the --tlsAllow‐
2460 ConnectionsWithoutCertificates is provided. The C Driver can be config‐
2461 ured to present a client certificate using the URI option tlsCertifi‐
2462 cateKeyFile, which may be referenced through the constant MON‐
2463 GOC_URI_TLSCERTIFICATEKEYFILE.
2464
2465 mongoc_client_t *client = NULL;
2466 mongoc_uri_t *uri = mongoc_uri_new ("mongodb://localhost:27017/?tls=true");
2467 mongoc_uri_set_option_as_utf8 (uri, MONGOC_URI_TLSCERTIFICATEKEYFILE, "client.pem");
2468
2469 client = mongoc_client_new_from_uri (uri);
2470
2471 The client certificate provided by tlsCertificateKeyFile must be issued
2472 by one of the server trusted Certificate Authorities listed in
2473 --tlsCAFile, or issued by a CA in the native certificate store on the
2474 server when omitted.
2475
2476 See Configuring TLS for more information on the various TLS related op‐
2477 tions.
2478
2479 Compressing data to and from MongoDB
2480 MongoDB 3.4 added Snappy compression support, zlib compression in 3.6,
2481 and zstd compression in 4.2. To enable compression support the client
2482 must be configured with which compressors to use:
2483
2484 mongoc_client_t *client = NULL;
2485 client = mongoc_client_new ("mongodb://localhost:27017/?compressors=snappy,zlib,zstd");
2486
2487 The compressors option specifies the priority order of compressors the
2488 client wants to use. Messages are compressed if the client and server
2489 share any compressors in common.
2490
2491 Note that the compressor used by the server might not be the same com‐
2492 pressor as the client used. For example, if the client uses the con‐
2493 nection string compressors=zlib,snappy the client will use zlib com‐
2494 pression to send data (if possible), but the server might still reply
2495 using snappy, depending on how the server was configured.
2496
2497 The driver must be built with zlib and/or snappy and/or zstd support to
2498 enable compression support, any unknown (or not compiled in) compressor
2499 value will be ignored. Note: to build with zstd requires cmake 3.12 or
2500 higher.
2501
2502 Additional Connection Options
2503 The full list of connection options can be found in the mongoc_uri_t
2504 docs.
2505
2506 Certain socket/connection related options are not configurable:
2507
2508 ┌──────────────┬─────────────────────┬─────────────────────┐
2509 │Option │ Description │ Value │
2510 ├──────────────┼─────────────────────┼─────────────────────┤
2511 │SO_KEEPALIVE │ TCP Keep Alive │ Enabled │
2512 ├──────────────┼─────────────────────┼─────────────────────┤
2513 │TCP_KEEPIDLE │ How long a connec‐ │ 120 seconds │
2514 │ │ tion needs to re‐ │ │
2515 │ │ main idle before │ │
2516 │ │ TCP starts sending │ │
2517 │ │ keepalive probes │ │
2518 ├──────────────┼─────────────────────┼─────────────────────┤
2519 │TCP_KEEPINTVL │ The time in seconds │ 10 seconds │
2520 │ │ between TCP probes │ │
2521 └──────────────┴─────────────────────┴─────────────────────┘
2522
2523
2524
2525
2526
2527 │TCP_KEEPCNT │ How many probes to │ 9 probes │
2528 │ │ send, without ac‐ │ │
2529 │ │ knowledgement, be‐ │ │
2530 │ │ fore dropping the │ │
2531 │ │ connection │ │
2532 ├──────────────┼─────────────────────┼─────────────────────┤
2533 │TCP_NODELAY │ Send packets as │ Enabled (no buffer‐ │
2534 │ │ soon as possible or │ ing) │
2535 │ │ buffer small pack‐ │ │
2536 │ │ ets (Nagle algo‐ │ │
2537 │ │ rithm) │ │
2538 └──────────────┴─────────────────────┴─────────────────────┘
2539
2540 Connection Pooling
2541 The MongoDB C driver has two connection modes: single-threaded and
2542 pooled. Single-threaded mode is optimized for embedding the driver
2543 within languages like PHP. Multi-threaded programs should use pooled
2544 mode: this mode minimizes the total connection count, and in pooled
2545 mode background threads monitor the MongoDB server topology, so the
2546 program need not block to scan it.
2547
2548 Single Mode
2549 In single mode, your program creates a mongoc_client_t directly:
2550
2551 mongoc_client_t *client = mongoc_client_new (
2552 "mongodb://hostA,hostB/?replicaSet=my_rs");
2553
2554 The client connects on demand when your program first uses it for a
2555 MongoDB operation. Using a non-blocking socket per server, it begins a
2556 check on each server concurrently, and uses the asynchronous poll or
2557 select function to receive events from the sockets, until all have re‐
2558 sponded or timed out. Put another way, in single-threaded mode the C
2559 Driver fans out to begin all checks concurrently, then fans in once all
2560 checks have completed or timed out. Once the scan completes, the client
2561 executes your program's operation and returns.
2562
2563 In single mode, the client re-scans the server topology roughly once
2564 per minute. If more than a minute has elapsed since the previous scan,
2565 the next operation on the client will block while the client completes
2566 its scan. This interval is configurable with heartbeatFrequencyMS in
2567 the connection string. (See mongoc_uri_t.)
2568
2569 A single client opens one connection per server in your topology: these
2570 connections are used both for scanning the topology and performing nor‐
2571 mal operations.
2572
2573 Pooled Mode
2574 To activate pooled mode, create a mongoc_client_pool_t:
2575
2576 mongoc_uri_t *uri = mongoc_uri_new (
2577 "mongodb://hostA,hostB/?replicaSet=my_rs");
2578
2579 mongoc_client_pool_t *pool = mongoc_client_pool_new (uri);
2580
2581 When your program first calls mongoc_client_pool_pop(), the pool
2582 launches monitoring threads in the background. Monitoring threads inde‐
2583 pendently connect to all servers in the connection string. As monitor‐
2584 ing threads receive hello responses from the servers, they update the
2585 shared view of the server topology. Additional monitoring threads and
2586 connections are created as new servers are discovered. Monitoring
2587 threads are terminated when servers are removed from the shared view of
2588 the server topology.
2589
2590 Each thread that executes MongoDB operations must check out a client
2591 from the pool:
2592
2593 mongoc_client_t *client = mongoc_client_pool_pop (pool);
2594
2595 /* use the client for operations ... */
2596
2597 mongoc_client_pool_push (pool, client);
2598
2599 The mongoc_client_t object is not thread-safe, only the
2600 mongoc_client_pool_t is.
2601
2602 When the driver is in pooled mode, your program's operations are un‐
2603 blocked as soon as monitoring discovers a usable server. For example,
2604 if a thread in your program is waiting to execute an "insert" on the
2605 primary, it is unblocked as soon as the primary is discovered, rather
2606 than waiting for all secondaries to be checked as well.
2607
2608 The pool opens one connection per server for monitoring, and each
2609 client opens its own connection to each server it uses for application
2610 operations. Background monitoring threads re-scan servers independently
2611 roughly every 10 seconds. This interval is configurable with heartbeat‐
2612 FrequencyMS in the connection string. (See mongoc_uri_t.)
2613
2614 The connection string can also specify waitQueueTimeoutMS to limit the
2615 time that mongoc_client_pool_pop() will wait for a client from the
2616 pool. (See mongoc_uri_t.) If waitQueueTimeoutMS is specified, then it
2617 is necessary to confirm that a client was actually returned:
2618
2619 mongoc_uri_t *uri = mongoc_uri_new (
2620 "mongodb://hostA,hostB/?replicaSet=my_rs&waitQueueTimeoutMS=1000");
2621
2622 mongoc_client_pool_t *pool = mongoc_client_pool_new (uri);
2623
2624 mongoc_client_t *client = mongoc_client_pool_pop (pool);
2625
2626 if (client) {
2627 /* use the client for operations ... */
2628
2629 mongoc_client_pool_push (pool, client);
2630 } else {
2631 /* take appropriate action for a timeout */
2632 }
2633
2634 See Connection Pool Options to configure pool size and behavior, and
2635 see mongoc_client_pool_t for an extended example of a multi-threaded
2636 program that uses the driver in pooled mode.
2637
2638 Cursors
2639 Handling Cursor Failures
2640 Cursors exist on a MongoDB server. However, the mongoc_cursor_t struc‐
2641 ture gives the local process a handle to the cursor. It is possible for
2642 errors to occur on the server while iterating a cursor on the client.
2643 Even a network partition may occur. This means that applications should
2644 be robust in handling cursor failures.
2645
2646 While iterating cursors, you should check to see if an error has oc‐
2647 curred. See the following example for how to robustly check for errors.
2648
2649 static void
2650 print_all_documents (mongoc_collection_t *collection)
2651 {
2652 mongoc_cursor_t *cursor;
2653 const bson_t *doc;
2654 bson_error_t error;
2655 bson_t query = BSON_INITIALIZER;
2656 char *str;
2657
2658 cursor = mongoc_collection_find_with_opts (collection, query, NULL, NULL);
2659
2660 while (mongoc_cursor_next (cursor, &doc)) {
2661 str = bson_as_canonical_extended_json (doc, NULL);
2662 printf ("%s\n", str);
2663 bson_free (str);
2664 }
2665
2666 if (mongoc_cursor_error (cursor, &error)) {
2667 fprintf (stderr, "Failed to iterate all documents: %s\n", error.message);
2668 }
2669
2670 mongoc_cursor_destroy (cursor);
2671 }
2672
2673 Destroying Server-Side Cursors
2674 The MongoDB C driver will automatically destroy a server-side cursor
2675 when mongoc_cursor_destroy() is called. Failure to call this function
2676 when done with a cursor will leak memory client side as well as consume
2677 extra memory server side. If the cursor was configured to never time‐
2678 out, it will become a memory leak on the server.
2679
2680 Tailable Cursors
2681 Tailable cursors are cursors that remain open even after they've re‐
2682 turned a final result. This way, if more documents are added to a col‐
2683 lection (i.e., to the cursor's result set), then you can continue to
2684 call mongoc_cursor_next() to retrieve those additional results.
2685
2686 Here's a complete test case that demonstrates the use of tailable cur‐
2687 sors.
2688
2689 NOTE:
2690 Tailable cursors are for capped collections only.
2691
2692 An example to tail the oplog from a replica set.
2693
2694 mongoc-tail.c
2695
2696 #include <bson/bson.h>
2697 #include <mongoc/mongoc.h>
2698 #include <stdio.h>
2699 #include <stdlib.h>
2700
2701 #ifdef _WIN32
2702 #define sleep(_n) Sleep ((_n) *1000)
2703 #endif
2704
2705
2706 static void
2707 print_bson (const bson_t *b)
2708 {
2709 char *str;
2710
2711 str = bson_as_canonical_extended_json (b, NULL);
2712 fprintf (stdout, "%s\n", str);
2713 bson_free (str);
2714 }
2715
2716
2717 static mongoc_cursor_t *
2718 query_collection (mongoc_collection_t *collection, uint32_t last_time)
2719 {
2720 mongoc_cursor_t *cursor;
2721 bson_t query;
2722 bson_t gt;
2723 bson_t opts;
2724
2725 BSON_ASSERT (collection);
2726
2727 bson_init (&query);
2728 BSON_APPEND_DOCUMENT_BEGIN (&query, "ts", >);
2729 BSON_APPEND_TIMESTAMP (>, "$gt", last_time, 0);
2730 bson_append_document_end (&query, >);
2731
2732 bson_init (&opts);
2733 BSON_APPEND_BOOL (&opts, "tailable", true);
2734 BSON_APPEND_BOOL (&opts, "awaitData", true);
2735
2736 cursor = mongoc_collection_find_with_opts (collection, &query, &opts, NULL);
2737
2738 bson_destroy (&query);
2739 bson_destroy (&opts);
2740
2741 return cursor;
2742 }
2743
2744
2745 static void
2746 tail_collection (mongoc_collection_t *collection)
2747 {
2748 mongoc_cursor_t *cursor;
2749 uint32_t last_time;
2750 const bson_t *doc;
2751 bson_error_t error;
2752 bson_iter_t iter;
2753
2754 BSON_ASSERT (collection);
2755
2756 last_time = (uint32_t) time (NULL);
2757
2758 while (true) {
2759 cursor = query_collection (collection, last_time);
2760 while (!mongoc_cursor_error (cursor, &error) &&
2761 mongoc_cursor_more (cursor)) {
2762 if (mongoc_cursor_next (cursor, &doc)) {
2763 if (bson_iter_init_find (&iter, doc, "ts") &&
2764 BSON_ITER_HOLDS_TIMESTAMP (&iter)) {
2765 bson_iter_timestamp (&iter, &last_time, NULL);
2766 }
2767 print_bson (doc);
2768 }
2769 }
2770 if (mongoc_cursor_error (cursor, &error)) {
2771 if (error.domain == MONGOC_ERROR_SERVER) {
2772 fprintf (stderr, "%s\n", error.message);
2773 exit (1);
2774 }
2775 }
2776
2777 mongoc_cursor_destroy (cursor);
2778 sleep (1);
2779 }
2780 }
2781
2782
2783 int
2784 main (int argc, char *argv[])
2785 {
2786 mongoc_collection_t *collection;
2787 mongoc_client_t *client;
2788 mongoc_uri_t *uri;
2789 bson_error_t error;
2790
2791 if (argc != 2) {
2792 fprintf (stderr, "usage: %s MONGO_URI\n", argv[0]);
2793 return EXIT_FAILURE;
2794 }
2795
2796 mongoc_init ();
2797
2798 uri = mongoc_uri_new_with_error (argv[1], &error);
2799 if (!uri) {
2800 fprintf (stderr,
2801 "failed to parse URI: %s\n"
2802 "error message: %s\n",
2803 argv[1],
2804 error.message);
2805 return EXIT_FAILURE;
2806 }
2807
2808 client = mongoc_client_new_from_uri (uri);
2809 if (!client) {
2810 return EXIT_FAILURE;
2811 }
2812
2813 mongoc_client_set_error_api (client, 2);
2814
2815 collection = mongoc_client_get_collection (client, "local", "oplog.rs");
2816
2817 tail_collection (collection);
2818
2819 mongoc_collection_destroy (collection);
2820 mongoc_uri_destroy (uri);
2821 mongoc_client_destroy (client);
2822
2823 return EXIT_SUCCESS;
2824 }
2825
2826
2827 Let's compile and run this example against a replica set to see updates
2828 as they are made.
2829
2830 $ gcc -Wall -o mongoc-tail mongoc-tail.c $(pkg-config --cflags --libs libmongoc-1.0)
2831 $ ./mongoc-tail mongodb://example.com/?replicaSet=myReplSet
2832 {
2833 "h" : -8458503739429355503,
2834 "ns" : "test.test",
2835 "o" : {
2836 "_id" : {
2837 "$oid" : "5372ab0a25164be923d10d50"
2838 }
2839 },
2840 "op" : "i",
2841 "ts" : {
2842 "$timestamp" : {
2843 "i" : 1,
2844 "t" : 1400023818
2845 }
2846 },
2847 "v" : 2
2848 }
2849
2850 The line of output is a sample from performing db.test.insert({}) from
2851 the mongo shell on the replica set.
2852
2853 SEE ALSO:
2854 mongoc_cursor_set_max_await_time_ms().
2855
2856
2857 Bulk Write Operations
2858 This tutorial explains how to take advantage of MongoDB C driver bulk
2859 write operation features. Executing write operations in batches reduces
2860 the number of network round trips, increasing write throughput.
2861
2862 Bulk Insert
2863 First we need to fetch a bulk operation handle from the
2864 mongoc_collection_t.
2865
2866 mongoc_bulk_operation_t *bulk =
2867 mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2868
2869 We can now start inserting documents to the bulk operation. These will
2870 be buffered until we execute the operation.
2871
2872 The bulk operation will coalesce insertions as a single batch for each
2873 consecutive call to mongoc_bulk_operation_insert(). This creates a
2874 pipelined effect when possible.
2875
2876 To execute the bulk operation and receive the result we call
2877 mongoc_bulk_operation_execute().
2878
2879 bulk1.c
2880
2881 #include <assert.h>
2882 #include <mongoc/mongoc.h>
2883 #include <stdio.h>
2884
2885 static void
2886 bulk1 (mongoc_collection_t *collection)
2887 {
2888 mongoc_bulk_operation_t *bulk;
2889 bson_error_t error;
2890 bson_t *doc;
2891 bson_t reply;
2892 char *str;
2893 bool ret;
2894 int i;
2895
2896 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2897
2898 for (i = 0; i < 10000; i++) {
2899 doc = BCON_NEW ("i", BCON_INT32 (i));
2900 mongoc_bulk_operation_insert (bulk, doc);
2901 bson_destroy (doc);
2902 }
2903
2904 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
2905
2906 str = bson_as_canonical_extended_json (&reply, NULL);
2907 printf ("%s\n", str);
2908 bson_free (str);
2909
2910 if (!ret) {
2911 fprintf (stderr, "Error: %s\n", error.message);
2912 }
2913
2914 bson_destroy (&reply);
2915 mongoc_bulk_operation_destroy (bulk);
2916 }
2917
2918 int
2919 main (void)
2920 {
2921 mongoc_client_t *client;
2922 mongoc_collection_t *collection;
2923 const char *uri_string = "mongodb://localhost/?appname=bulk1-example";
2924 mongoc_uri_t *uri;
2925 bson_error_t error;
2926
2927 mongoc_init ();
2928
2929 uri = mongoc_uri_new_with_error (uri_string, &error);
2930 if (!uri) {
2931 fprintf (stderr,
2932 "failed to parse URI: %s\n"
2933 "error message: %s\n",
2934 uri_string,
2935 error.message);
2936 return EXIT_FAILURE;
2937 }
2938
2939 client = mongoc_client_new_from_uri (uri);
2940 if (!client) {
2941 return EXIT_FAILURE;
2942 }
2943
2944 mongoc_client_set_error_api (client, 2);
2945 collection = mongoc_client_get_collection (client, "test", "test");
2946
2947 bulk1 (collection);
2948
2949 mongoc_uri_destroy (uri);
2950 mongoc_collection_destroy (collection);
2951 mongoc_client_destroy (client);
2952
2953 mongoc_cleanup ();
2954
2955 return EXIT_SUCCESS;
2956 }
2957
2958
2959 Example reply document:
2960
2961 {"nInserted" : 10000,
2962 "nMatched" : 0,
2963 "nModified" : 0,
2964 "nRemoved" : 0,
2965 "nUpserted" : 0,
2966 "writeErrors" : []
2967 "writeConcernErrors" : [] }
2968
2969 Mixed Bulk Write Operations
2970 MongoDB C driver also supports executing mixed bulk write operations. A
2971 batch of insert, update, and remove operations can be executed together
2972 using the bulk write operations API.
2973
2974 Ordered Bulk Write Operations
2975 Ordered bulk write operations are batched and sent to the server in the
2976 order provided for serial execution. The reply document describes the
2977 type and count of operations performed.
2978
2979 bulk2.c
2980
2981 #include <assert.h>
2982 #include <mongoc/mongoc.h>
2983 #include <stdio.h>
2984
2985 static void
2986 bulk2 (mongoc_collection_t *collection)
2987 {
2988 mongoc_bulk_operation_t *bulk;
2989 bson_error_t error;
2990 bson_t *query;
2991 bson_t *doc;
2992 bson_t *opts;
2993 bson_t reply;
2994 char *str;
2995 bool ret;
2996 int i;
2997
2998 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
2999
3000 /* Remove everything */
3001 query = bson_new ();
3002 mongoc_bulk_operation_remove (bulk, query);
3003 bson_destroy (query);
3004
3005 /* Add a few documents */
3006 for (i = 1; i < 4; i++) {
3007 doc = BCON_NEW ("_id", BCON_INT32 (i));
3008 mongoc_bulk_operation_insert (bulk, doc);
3009 bson_destroy (doc);
3010 }
3011
3012 /* {_id: 1} => {$set: {foo: "bar"}} */
3013 query = BCON_NEW ("_id", BCON_INT32 (1));
3014 doc = BCON_NEW ("$set", "{", "foo", BCON_UTF8 ("bar"), "}");
3015 mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, NULL, &error);
3016 bson_destroy (query);
3017 bson_destroy (doc);
3018
3019 /* {_id: 4} => {'$inc': {'j': 1}} (upsert) */
3020 opts = BCON_NEW ("upsert", BCON_BOOL (true));
3021 query = BCON_NEW ("_id", BCON_INT32 (4));
3022 doc = BCON_NEW ("$inc", "{", "j", BCON_INT32 (1), "}");
3023 mongoc_bulk_operation_update_many_with_opts (bulk, query, doc, opts, &error);
3024 bson_destroy (query);
3025 bson_destroy (doc);
3026 bson_destroy (opts);
3027
3028 /* replace {j:1} with {j:2} */
3029 query = BCON_NEW ("j", BCON_INT32 (1));
3030 doc = BCON_NEW ("j", BCON_INT32 (2));
3031 mongoc_bulk_operation_replace_one_with_opts (bulk, query, doc, NULL, &error);
3032 bson_destroy (query);
3033 bson_destroy (doc);
3034
3035 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3036
3037 str = bson_as_canonical_extended_json (&reply, NULL);
3038 printf ("%s\n", str);
3039 bson_free (str);
3040
3041 if (!ret) {
3042 printf ("Error: %s\n", error.message);
3043 }
3044
3045 bson_destroy (&reply);
3046 mongoc_bulk_operation_destroy (bulk);
3047 }
3048
3049 int
3050 main (void)
3051 {
3052 mongoc_client_t *client;
3053 mongoc_collection_t *collection;
3054 const char *uri_string = "mongodb://localhost/?appname=bulk2-example";
3055 mongoc_uri_t *uri;
3056 bson_error_t error;
3057
3058 mongoc_init ();
3059
3060 uri = mongoc_uri_new_with_error (uri_string, &error);
3061 if (!uri) {
3062 fprintf (stderr,
3063 "failed to parse URI: %s\n"
3064 "error message: %s\n",
3065 uri_string,
3066 error.message);
3067 return EXIT_FAILURE;
3068 }
3069
3070 client = mongoc_client_new_from_uri (uri);
3071 if (!client) {
3072 return EXIT_FAILURE;
3073 }
3074
3075 mongoc_client_set_error_api (client, 2);
3076 collection = mongoc_client_get_collection (client, "test", "test");
3077
3078 bulk2 (collection);
3079
3080 mongoc_uri_destroy (uri);
3081 mongoc_collection_destroy (collection);
3082 mongoc_client_destroy (client);
3083
3084 mongoc_cleanup ();
3085
3086 return EXIT_SUCCESS;
3087 }
3088
3089
3090 Example reply document:
3091
3092 { "nInserted" : 3,
3093 "nMatched" : 2,
3094 "nModified" : 2,
3095 "nRemoved" : 10000,
3096 "nUpserted" : 1,
3097 "upserted" : [{"index" : 5, "_id" : 4}],
3098 "writeErrors" : []
3099 "writeConcernErrors" : [] }
3100
3101 The index field in the upserted array is the 0-based index of the up‐
3102 sert operation; in this example, the sixth operation of the overall
3103 bulk operation was an upsert, so its index is 5.
3104
3105 Unordered Bulk Write Operations
3106 Unordered bulk write operations are batched and sent to the server in
3107 arbitrary order where they may be executed in parallel. Any errors that
3108 occur are reported after all operations are attempted.
3109
3110 In the next example the first and third operations fail due to the
3111 unique constraint on _id. Since we are doing unordered execution the
3112 second and fourth operations succeed.
3113
3114 bulk3.c
3115
3116 #include <assert.h>
3117 #include <mongoc/mongoc.h>
3118 #include <stdio.h>
3119
3120 static void
3121 bulk3 (mongoc_collection_t *collection)
3122 {
3123 bson_t opts = BSON_INITIALIZER;
3124 mongoc_bulk_operation_t *bulk;
3125 bson_error_t error;
3126 bson_t *query;
3127 bson_t *doc;
3128 bson_t reply;
3129 char *str;
3130 bool ret;
3131
3132 /* false indicates unordered */
3133 BSON_APPEND_BOOL (&opts, "ordered", false);
3134 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3135 bson_destroy (&opts);
3136
3137 /* Add a document */
3138 doc = BCON_NEW ("_id", BCON_INT32 (1));
3139 mongoc_bulk_operation_insert (bulk, doc);
3140 bson_destroy (doc);
3141
3142 /* remove {_id: 2} */
3143 query = BCON_NEW ("_id", BCON_INT32 (2));
3144 mongoc_bulk_operation_remove_one (bulk, query);
3145 bson_destroy (query);
3146
3147 /* insert {_id: 3} */
3148 doc = BCON_NEW ("_id", BCON_INT32 (3));
3149 mongoc_bulk_operation_insert (bulk, doc);
3150 bson_destroy (doc);
3151
3152 /* replace {_id:4} {'i': 1} */
3153 query = BCON_NEW ("_id", BCON_INT32 (4));
3154 doc = BCON_NEW ("i", BCON_INT32 (1));
3155 mongoc_bulk_operation_replace_one (bulk, query, doc, false);
3156 bson_destroy (query);
3157 bson_destroy (doc);
3158
3159 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3160
3161 str = bson_as_canonical_extended_json (&reply, NULL);
3162 printf ("%s\n", str);
3163 bson_free (str);
3164
3165 if (!ret) {
3166 printf ("Error: %s\n", error.message);
3167 }
3168
3169 bson_destroy (&reply);
3170 mongoc_bulk_operation_destroy (bulk);
3171 bson_destroy (&opts);
3172 }
3173
3174 int
3175 main (void)
3176 {
3177 mongoc_client_t *client;
3178 mongoc_collection_t *collection;
3179 const char *uri_string = "mongodb://localhost/?appname=bulk3-example";
3180 mongoc_uri_t *uri;
3181 bson_error_t error;
3182
3183 mongoc_init ();
3184
3185 uri = mongoc_uri_new_with_error (uri_string, &error);
3186 if (!uri) {
3187 fprintf (stderr,
3188 "failed to parse URI: %s\n"
3189 "error message: %s\n",
3190 uri_string,
3191 error.message);
3192 return EXIT_FAILURE;
3193 }
3194
3195 client = mongoc_client_new_from_uri (uri);
3196 if (!client) {
3197 return EXIT_FAILURE;
3198 }
3199
3200 mongoc_client_set_error_api (client, 2);
3201 collection = mongoc_client_get_collection (client, "test", "test");
3202
3203 bulk3 (collection);
3204
3205 mongoc_uri_destroy (uri);
3206 mongoc_collection_destroy (collection);
3207 mongoc_client_destroy (client);
3208
3209 mongoc_cleanup ();
3210
3211 return EXIT_SUCCESS;
3212 }
3213
3214
3215 Example reply document:
3216
3217 { "nInserted" : 0,
3218 "nMatched" : 1,
3219 "nModified" : 1,
3220 "nRemoved" : 1,
3221 "nUpserted" : 0,
3222 "writeErrors" : [
3223 { "index" : 0,
3224 "code" : 11000,
3225 "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }" },
3226 { "index" : 2,
3227 "code" : 11000,
3228 "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 3 }" } ],
3229 "writeConcernErrors" : [] }
3230
3231 Error: E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }
3232
3233 The bson_error_t domain is MONGOC_ERROR_COMMAND and its code is 11000.
3234
3235 Bulk Operation Bypassing Document Validation
3236 This feature is only available when using MongoDB 3.2 and later.
3237
3238 By default bulk operations are validated against the schema, if any is
3239 defined. In certain cases however it may be necessary to bypass the
3240 document validation.
3241
3242 bulk5.c
3243
3244 #include <assert.h>
3245 #include <mongoc/mongoc.h>
3246 #include <stdio.h>
3247
3248 static void
3249 bulk5_fail (mongoc_collection_t *collection)
3250 {
3251 mongoc_bulk_operation_t *bulk;
3252 bson_error_t error;
3253 bson_t *doc;
3254 bson_t reply;
3255 char *str;
3256 bool ret;
3257
3258 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3259
3260 /* Two inserts */
3261 doc = BCON_NEW ("_id", BCON_INT32 (31));
3262 mongoc_bulk_operation_insert (bulk, doc);
3263 bson_destroy (doc);
3264
3265 doc = BCON_NEW ("_id", BCON_INT32 (32));
3266 mongoc_bulk_operation_insert (bulk, doc);
3267 bson_destroy (doc);
3268
3269 /* The above documents do not comply to the schema validation rules
3270 * we created previously, so this will result in an error */
3271 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3272
3273 str = bson_as_canonical_extended_json (&reply, NULL);
3274 printf ("%s\n", str);
3275 bson_free (str);
3276
3277 if (!ret) {
3278 printf ("Error: %s\n", error.message);
3279 }
3280
3281 bson_destroy (&reply);
3282 mongoc_bulk_operation_destroy (bulk);
3283 }
3284
3285 static void
3286 bulk5_success (mongoc_collection_t *collection)
3287 {
3288 mongoc_bulk_operation_t *bulk;
3289 bson_error_t error;
3290 bson_t *doc;
3291 bson_t reply;
3292 char *str;
3293 bool ret;
3294
3295 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3296
3297 /* Allow this document to bypass document validation.
3298 * NOTE: When authentication is enabled, the authenticated user must have
3299 * either the "dbadmin" or "restore" roles to bypass document validation */
3300 mongoc_bulk_operation_set_bypass_document_validation (bulk, true);
3301
3302 /* Two inserts */
3303 doc = BCON_NEW ("_id", BCON_INT32 (31));
3304 mongoc_bulk_operation_insert (bulk, doc);
3305 bson_destroy (doc);
3306
3307 doc = BCON_NEW ("_id", BCON_INT32 (32));
3308 mongoc_bulk_operation_insert (bulk, doc);
3309 bson_destroy (doc);
3310
3311 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3312
3313 str = bson_as_canonical_extended_json (&reply, NULL);
3314 printf ("%s\n", str);
3315 bson_free (str);
3316
3317 if (!ret) {
3318 printf ("Error: %s\n", error.message);
3319 }
3320
3321 bson_destroy (&reply);
3322 mongoc_bulk_operation_destroy (bulk);
3323 }
3324
3325 int
3326 main (void)
3327 {
3328 bson_t *options;
3329 bson_error_t error;
3330 mongoc_client_t *client;
3331 mongoc_collection_t *collection;
3332 mongoc_database_t *database;
3333 const char *uri_string = "mongodb://localhost/?appname=bulk5-example";
3334 mongoc_uri_t *uri;
3335
3336 mongoc_init ();
3337
3338 uri = mongoc_uri_new_with_error (uri_string, &error);
3339 if (!uri) {
3340 fprintf (stderr,
3341 "failed to parse URI: %s\n"
3342 "error message: %s\n",
3343 uri_string,
3344 error.message);
3345 return EXIT_FAILURE;
3346 }
3347
3348 client = mongoc_client_new_from_uri (uri);
3349 if (!client) {
3350 return EXIT_FAILURE;
3351 }
3352
3353 mongoc_client_set_error_api (client, 2);
3354 database = mongoc_client_get_database (client, "testasdf");
3355
3356 /* Create schema validator */
3357 options = BCON_NEW (
3358 "validator", "{", "number", "{", "$gte", BCON_INT32 (5), "}", "}");
3359 collection =
3360 mongoc_database_create_collection (database, "collname", options, &error);
3361
3362 if (collection) {
3363 bulk5_fail (collection);
3364 bulk5_success (collection);
3365 mongoc_collection_destroy (collection);
3366 } else {
3367 fprintf (stderr, "Couldn't create collection: '%s'\n", error.message);
3368 }
3369
3370 bson_free (options);
3371 mongoc_uri_destroy (uri);
3372 mongoc_database_destroy (database);
3373 mongoc_client_destroy (client);
3374
3375 mongoc_cleanup ();
3376
3377 return EXIT_SUCCESS;
3378 }
3379
3380
3381 Running the above example will result in:
3382
3383 { "nInserted" : 0,
3384 "nMatched" : 0,
3385 "nModified" : 0,
3386 "nRemoved" : 0,
3387 "nUpserted" : 0,
3388 "writeErrors" : [
3389 { "index" : 0,
3390 "code" : 121,
3391 "errmsg" : "Document failed validation" } ] }
3392
3393 Error: Document failed validation
3394
3395 { "nInserted" : 2,
3396 "nMatched" : 0,
3397 "nModified" : 0,
3398 "nRemoved" : 0,
3399 "nUpserted" : 0,
3400 "writeErrors" : [] }
3401
3402 The bson_error_t domain is MONGOC_ERROR_COMMAND.
3403
3404 Bulk Operation Write Concerns
3405 By default bulk operations are executed with the write_concern of the
3406 collection they are executed against. A custom write concern can be
3407 passed to the mongoc_collection_create_bulk_operation_with_opts()
3408 method. Write concern errors (e.g. wtimeout) will be reported after all
3409 operations are attempted, regardless of execution order.
3410
3411 bulk4.c
3412
3413 #include <assert.h>
3414 #include <mongoc/mongoc.h>
3415 #include <stdio.h>
3416
3417 static void
3418 bulk4 (mongoc_collection_t *collection)
3419 {
3420 bson_t opts = BSON_INITIALIZER;
3421 mongoc_write_concern_t *wc;
3422 mongoc_bulk_operation_t *bulk;
3423 bson_error_t error;
3424 bson_t *doc;
3425 bson_t reply;
3426 char *str;
3427 bool ret;
3428
3429 wc = mongoc_write_concern_new ();
3430 mongoc_write_concern_set_w (wc, 4);
3431 mongoc_write_concern_set_wtimeout_int64 (wc, 100); /* milliseconds */
3432 mongoc_write_concern_append (wc, &opts);
3433
3434 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3435
3436 /* Two inserts */
3437 doc = BCON_NEW ("_id", BCON_INT32 (10));
3438 mongoc_bulk_operation_insert (bulk, doc);
3439 bson_destroy (doc);
3440
3441 doc = BCON_NEW ("_id", BCON_INT32 (11));
3442 mongoc_bulk_operation_insert (bulk, doc);
3443 bson_destroy (doc);
3444
3445 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3446
3447 str = bson_as_canonical_extended_json (&reply, NULL);
3448 printf ("%s\n", str);
3449 bson_free (str);
3450
3451 if (!ret) {
3452 printf ("Error: %s\n", error.message);
3453 }
3454
3455 bson_destroy (&reply);
3456 mongoc_bulk_operation_destroy (bulk);
3457 mongoc_write_concern_destroy (wc);
3458 bson_destroy (&opts);
3459 }
3460
3461 int
3462 main (void)
3463 {
3464 mongoc_client_t *client;
3465 mongoc_collection_t *collection;
3466 const char *uri_string = "mongodb://localhost/?appname=bulk4-example";
3467 mongoc_uri_t *uri;
3468 bson_error_t error;
3469
3470 mongoc_init ();
3471
3472 uri = mongoc_uri_new_with_error (uri_string, &error);
3473 if (!uri) {
3474 fprintf (stderr,
3475 "failed to parse URI: %s\n"
3476 "error message: %s\n",
3477 uri_string,
3478 error.message);
3479 return EXIT_FAILURE;
3480 }
3481
3482 client = mongoc_client_new_from_uri (uri);
3483 if (!client) {
3484 return EXIT_FAILURE;
3485 }
3486
3487 mongoc_client_set_error_api (client, 2);
3488 collection = mongoc_client_get_collection (client, "test", "test");
3489
3490 bulk4 (collection);
3491
3492 mongoc_uri_destroy (uri);
3493 mongoc_collection_destroy (collection);
3494 mongoc_client_destroy (client);
3495
3496 mongoc_cleanup ();
3497
3498 return EXIT_SUCCESS;
3499 }
3500
3501
3502 Example reply document and error message:
3503
3504 { "nInserted" : 2,
3505 "nMatched" : 0,
3506 "nModified" : 0,
3507 "nRemoved" : 0,
3508 "nUpserted" : 0,
3509 "writeErrors" : [],
3510 "writeConcernErrors" : [
3511 { "code" : 64,
3512 "errmsg" : "waiting for replication timed out" }
3513 ] }
3514
3515 Error: waiting for replication timed out
3516
3517 The bson_error_t domain is MONGOC_ERROR_WRITE_CONCERN if there are
3518 write concern errors and no write errors. Write errors indicate failed
3519 operations, so they take precedence over write concern errors, which
3520 mean merely that the write concern is not satisfied yet.
3521
3522 Setting Collation Order
3523 This feature is only available when using MongoDB 3.4 and later.
3524
3525 bulk-collation.c
3526
3527 #include <mongoc/mongoc.h>
3528 #include <stdio.h>
3529
3530 static void
3531 bulk_collation (mongoc_collection_t *collection)
3532 {
3533 mongoc_bulk_operation_t *bulk;
3534 bson_t *opts;
3535 bson_t *doc;
3536 bson_t *selector;
3537 bson_t *update;
3538 bson_error_t error;
3539 bson_t reply;
3540 char *str;
3541 uint32_t ret;
3542
3543 /* insert {_id: "one"} and {_id: "One"} */
3544 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3545 doc = BCON_NEW ("_id", BCON_UTF8 ("one"));
3546 mongoc_bulk_operation_insert (bulk, doc);
3547 bson_destroy (doc);
3548
3549 doc = BCON_NEW ("_id", BCON_UTF8 ("One"));
3550 mongoc_bulk_operation_insert (bulk, doc);
3551 bson_destroy (doc);
3552
3553 /* "One" normally sorts before "one"; make "one" come first */
3554 opts = BCON_NEW ("collation",
3555 "{",
3556 "locale",
3557 BCON_UTF8 ("en_US"),
3558 "caseFirst",
3559 BCON_UTF8 ("lower"),
3560 "}");
3561
3562 /* set x=1 on the document with _id "One", which now sorts after "one" */
3563 update = BCON_NEW ("$set", "{", "x", BCON_INT64 (1), "}");
3564 selector = BCON_NEW ("_id", "{", "$gt", BCON_UTF8 ("one"), "}");
3565 mongoc_bulk_operation_update_one_with_opts (
3566 bulk, selector, update, opts, &error);
3567
3568 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3569
3570 str = bson_as_canonical_extended_json (&reply, NULL);
3571 printf ("%s\n", str);
3572 bson_free (str);
3573
3574 if (!ret) {
3575 printf ("Error: %s\n", error.message);
3576 }
3577
3578 bson_destroy (&reply);
3579 bson_destroy (update);
3580 bson_destroy (selector);
3581 bson_destroy (opts);
3582 mongoc_bulk_operation_destroy (bulk);
3583 }
3584
3585 int
3586 main (void)
3587 {
3588 mongoc_client_t *client;
3589 mongoc_collection_t *collection;
3590 const char *uri_string = "mongodb://localhost/?appname=bulk-collation";
3591 mongoc_uri_t *uri;
3592 bson_error_t error;
3593
3594 mongoc_init ();
3595
3596 uri = mongoc_uri_new_with_error (uri_string, &error);
3597 if (!uri) {
3598 fprintf (stderr,
3599 "failed to parse URI: %s\n"
3600 "error message: %s\n",
3601 uri_string,
3602 error.message);
3603 return EXIT_FAILURE;
3604 }
3605
3606 client = mongoc_client_new_from_uri (uri);
3607 if (!client) {
3608 return EXIT_FAILURE;
3609 }
3610
3611 mongoc_client_set_error_api (client, 2);
3612 collection = mongoc_client_get_collection (client, "db", "collection");
3613 bulk_collation (collection);
3614
3615 mongoc_uri_destroy (uri);
3616 mongoc_collection_destroy (collection);
3617 mongoc_client_destroy (client);
3618
3619 mongoc_cleanup ();
3620
3621 return EXIT_SUCCESS;
3622 }
3623
3624
3625 Running the above example will result in:
3626
3627 { "nInserted" : 2,
3628 "nMatched" : 1,
3629 "nModified" : 1,
3630 "nRemoved" : 0,
3631 "nUpserted" : 0,
3632 "writeErrors" : [ ]
3633 }
3634
3635 Unacknowledged Bulk Writes
3636 Set "w" to zero for an unacknowledged write. The driver sends unac‐
3637 knowledged writes using the legacy opcodes OP_INSERT, OP_UPDATE, and
3638 OP_DELETE.
3639
3640 bulk6.c
3641
3642 #include <mongoc/mongoc.h>
3643 #include <stdio.h>
3644
3645 static void
3646 bulk6 (mongoc_collection_t *collection)
3647 {
3648 bson_t opts = BSON_INITIALIZER;
3649 mongoc_write_concern_t *wc;
3650 mongoc_bulk_operation_t *bulk;
3651 bson_error_t error;
3652 bson_t *doc;
3653 bson_t *selector;
3654 bson_t reply;
3655 char *str;
3656 bool ret;
3657
3658 wc = mongoc_write_concern_new ();
3659 mongoc_write_concern_set_w (wc, 0);
3660 mongoc_write_concern_append (wc, &opts);
3661
3662 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, &opts);
3663
3664 doc = BCON_NEW ("_id", BCON_INT32 (10));
3665 mongoc_bulk_operation_insert (bulk, doc);
3666 bson_destroy (doc);
3667
3668 selector = BCON_NEW ("_id", BCON_INT32 (11));
3669 mongoc_bulk_operation_remove_one (bulk, selector);
3670 bson_destroy (selector);
3671
3672 ret = mongoc_bulk_operation_execute (bulk, &reply, &error);
3673
3674 str = bson_as_canonical_extended_json (&reply, NULL);
3675 printf ("%s\n", str);
3676 bson_free (str);
3677
3678 if (!ret) {
3679 printf ("Error: %s\n", error.message);
3680 }
3681
3682 bson_destroy (&reply);
3683 mongoc_bulk_operation_destroy (bulk);
3684 mongoc_write_concern_destroy (wc);
3685 bson_destroy (&opts);
3686 }
3687
3688 int
3689 main (void)
3690 {
3691 mongoc_client_t *client;
3692 mongoc_collection_t *collection;
3693 const char *uri_string = "mongodb://localhost/?appname=bulk6-example";
3694 mongoc_uri_t *uri;
3695 bson_error_t error;
3696
3697 mongoc_init ();
3698
3699 uri = mongoc_uri_new_with_error (uri_string, &error);
3700 if (!uri) {
3701 fprintf (stderr,
3702 "failed to parse URI: %s\n"
3703 "error message: %s\n",
3704 uri_string,
3705 error.message);
3706 return EXIT_FAILURE;
3707 }
3708
3709 client = mongoc_client_new_from_uri (uri);
3710 if (!client) {
3711 return EXIT_FAILURE;
3712 }
3713
3714 mongoc_client_set_error_api (client, 2);
3715 collection = mongoc_client_get_collection (client, "test", "test");
3716
3717 bulk6 (collection);
3718
3719 mongoc_uri_destroy (uri);
3720 mongoc_collection_destroy (collection);
3721 mongoc_client_destroy (client);
3722
3723 mongoc_cleanup ();
3724
3725 return EXIT_SUCCESS;
3726 }
3727
3728
3729 The reply document is empty:
3730
3731 { }
3732
3733 Further Reading
3734 See the Driver Bulk API Spec, which describes bulk write operations for
3735 all MongoDB drivers.
3736
3737 Aggregation Framework Examples
3738 This document provides a number of practical examples that display the
3739 capabilities of the aggregation framework.
3740
3741 The Aggregations using the Zip Codes Data Set examples uses a publicly
3742 available data set of all zipcodes and populations in the United
3743 States. These data are available at: zips.json.
3744
3745 Requirements
3746 Let's check if everything is installed.
3747
3748 Use the following command to load zips.json data set into mongod in‐
3749 stance:
3750
3751 $ mongoimport --drop -d test -c zipcodes zips.json
3752
3753 Let's use the MongoDB shell to verify that everything was imported suc‐
3754 cessfully.
3755
3756 $ mongo test
3757 connecting to: test
3758 > db.zipcodes.count()
3759 29467
3760 > db.zipcodes.findOne()
3761 {
3762 "_id" : "35004",
3763 "city" : "ACMAR",
3764 "loc" : [
3765 -86.51557,
3766 33.584132
3767 ],
3768 "pop" : 6055,
3769 "state" : "AL"
3770 }
3771
3772 Aggregations using the Zip Codes Data Set
3773 Each document in this collection has the following form:
3774
3775 {
3776 "_id" : "35004",
3777 "city" : "Acmar",
3778 "state" : "AL",
3779 "pop" : 6055,
3780 "loc" : [-86.51557, 33.584132]
3781 }
3782
3783 In these documents:
3784
3785 • The _id field holds the zipcode as a string.
3786
3787 • The city field holds the city name.
3788
3789 • The state field holds the two letter state abbreviation.
3790
3791 • The pop field holds the population.
3792
3793 • The loc field holds the location as a [latitude, longitude] array.
3794
3795 States with Populations Over 10 Million
3796 To get all states with a population greater than 10 million, use the
3797 following aggregation pipeline:
3798
3799 aggregation1.c
3800
3801 #include <mongoc/mongoc.h>
3802 #include <stdio.h>
3803
3804 static void
3805 print_pipeline (mongoc_collection_t *collection)
3806 {
3807 mongoc_cursor_t *cursor;
3808 bson_error_t error;
3809 const bson_t *doc;
3810 bson_t *pipeline;
3811 char *str;
3812
3813 pipeline = BCON_NEW ("pipeline",
3814 "[",
3815 "{",
3816 "$group",
3817 "{",
3818 "_id",
3819 "$state",
3820 "total_pop",
3821 "{",
3822 "$sum",
3823 "$pop",
3824 "}",
3825 "}",
3826 "}",
3827 "{",
3828 "$match",
3829 "{",
3830 "total_pop",
3831 "{",
3832 "$gte",
3833 BCON_INT32 (10000000),
3834 "}",
3835 "}",
3836 "}",
3837 "]");
3838
3839 cursor = mongoc_collection_aggregate (
3840 collection, MONGOC_QUERY_NONE, pipeline, NULL, NULL);
3841
3842 while (mongoc_cursor_next (cursor, &doc)) {
3843 str = bson_as_canonical_extended_json (doc, NULL);
3844 printf ("%s\n", str);
3845 bson_free (str);
3846 }
3847
3848 if (mongoc_cursor_error (cursor, &error)) {
3849 fprintf (stderr, "Cursor Failure: %s\n", error.message);
3850 }
3851
3852 mongoc_cursor_destroy (cursor);
3853 bson_destroy (pipeline);
3854 }
3855
3856 int
3857 main (void)
3858 {
3859 mongoc_client_t *client;
3860 mongoc_collection_t *collection;
3861 const char *uri_string =
3862 "mongodb://localhost:27017/?appname=aggregation-example";
3863 mongoc_uri_t *uri;
3864 bson_error_t error;
3865
3866 mongoc_init ();
3867
3868 uri = mongoc_uri_new_with_error (uri_string, &error);
3869 if (!uri) {
3870 fprintf (stderr,
3871 "failed to parse URI: %s\n"
3872 "error message: %s\n",
3873 uri_string,
3874 error.message);
3875 return EXIT_FAILURE;
3876 }
3877
3878 client = mongoc_client_new_from_uri (uri);
3879 if (!client) {
3880 return EXIT_FAILURE;
3881 }
3882
3883 mongoc_client_set_error_api (client, 2);
3884 collection = mongoc_client_get_collection (client, "test", "zipcodes");
3885
3886 print_pipeline (collection);
3887
3888 mongoc_uri_destroy (uri);
3889 mongoc_collection_destroy (collection);
3890 mongoc_client_destroy (client);
3891
3892 mongoc_cleanup ();
3893
3894 return EXIT_SUCCESS;
3895 }
3896
3897
3898 You should see a result like the following:
3899
3900 { "_id" : "PA", "total_pop" : 11881643 }
3901 { "_id" : "OH", "total_pop" : 10847115 }
3902 { "_id" : "NY", "total_pop" : 17990455 }
3903 { "_id" : "FL", "total_pop" : 12937284 }
3904 { "_id" : "TX", "total_pop" : 16986510 }
3905 { "_id" : "IL", "total_pop" : 11430472 }
3906 { "_id" : "CA", "total_pop" : 29760021 }
3907
3908 The above aggregation pipeline is build from two pipeline operators:
3909 $group and $match.
3910
3911 The $group pipeline operator requires _id field where we specify group‐
3912 ing; remaining fields specify how to generate composite value and must
3913 use one of the group aggregation functions: $addToSet, $first, $last,
3914 $max, $min, $avg, $push, $sum. The $match pipeline operator syntax is
3915 the same as the read operation query syntax.
3916
3917 The $group process reads all documents and for each state it creates a
3918 separate document, for example:
3919
3920 { "_id" : "WA", "total_pop" : 4866692 }
3921
3922 The total_pop field uses the $sum aggregation function to sum the val‐
3923 ues of all pop fields in the source documents.
3924
3925 Documents created by $group are piped to the $match pipeline operator.
3926 It returns the documents with the value of total_pop field greater than
3927 or equal to 10 million.
3928
3929 Average City Population by State
3930 To get the first three states with the greatest average population per
3931 city, use the following aggregation:
3932
3933 pipeline = BCON_NEW ("pipeline", "[",
3934 "{", "$group", "{", "_id", "{", "state", "$state", "city", "$city", "}", "pop", "{", "$sum", "$pop", "}", "}", "}",
3935 "{", "$group", "{", "_id", "$_id.state", "avg_city_pop", "{", "$avg", "$pop", "}", "}", "}",
3936 "{", "$sort", "{", "avg_city_pop", BCON_INT32 (-1), "}", "}",
3937 "{", "$limit", BCON_INT32 (3) "}",
3938 "]");
3939
3940 This aggregate pipeline produces:
3941
3942 { "_id" : "DC", "avg_city_pop" : 303450.0 }
3943 { "_id" : "FL", "avg_city_pop" : 27942.29805615551 }
3944 { "_id" : "CA", "avg_city_pop" : 27735.341099720412 }
3945
3946 The above aggregation pipeline is build from three pipeline operators:
3947 $group, $sort and $limit.
3948
3949 The first $group operator creates the following documents:
3950
3951 { "_id" : { "state" : "WY", "city" : "Smoot" }, "pop" : 414 }
3952
3953 Note, that the $group operator can't use nested documents except the
3954 _id field.
3955
3956 The second $group uses these documents to create the following docu‐
3957 ments:
3958
3959 { "_id" : "FL", "avg_city_pop" : 27942.29805615551 }
3960
3961 These documents are sorted by the avg_city_pop field in descending or‐
3962 der. Finally, the $limit pipeline operator returns the first 3 docu‐
3963 ments from the sorted set.
3964
3965 "distinct" and "mapReduce"
3966 This document provides some practical, simple, examples to demonstrate
3967 the distinct and mapReduce commands.
3968
3969 Setup
3970 First we'll write some code to insert sample data:
3971
3972 doc-common-insert.c
3973
3974 /* Don't try to compile this file on its own. It's meant to be #included
3975 by example code */
3976
3977 /* Insert some sample data */
3978 bool
3979 insert_data (mongoc_collection_t *collection)
3980 {
3981 mongoc_bulk_operation_t *bulk;
3982 enum N { ndocs = 4 };
3983 bson_t *docs[ndocs];
3984 bson_error_t error;
3985 int i = 0;
3986 bool ret;
3987
3988 bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);
3989
3990 docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
3991 docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
3992 docs[2] = BCON_NEW (
3993 "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
3994 docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");
3995
3996 for (i = 0; i < ndocs; i++) {
3997 mongoc_bulk_operation_insert (bulk, docs[i]);
3998 bson_destroy (docs[i]);
3999 docs[i] = NULL;
4000 }
4001
4002 ret = mongoc_bulk_operation_execute (bulk, NULL, &error);
4003
4004 if (!ret) {
4005 fprintf (stderr, "Error inserting data: %s\n", error.message);
4006 }
4007
4008 mongoc_bulk_operation_destroy (bulk);
4009 return ret;
4010 }
4011
4012 /* A helper which we'll use a lot later on */
4013 void
4014 print_res (const bson_t *reply)
4015 {
4016 char *str;
4017 BSON_ASSERT (reply);
4018 str = bson_as_canonical_extended_json (reply, NULL);
4019 printf ("%s\n", str);
4020 bson_free (str);
4021 }
4022
4023
4024 "distinct" command
4025 This is how to use the distinct command to get the distinct values of x
4026 which are greater than 1:
4027
4028 distinct.c
4029
4030 bool
4031 distinct (mongoc_database_t *database)
4032 {
4033 bson_t *command;
4034 bson_t reply;
4035 bson_error_t error;
4036 bool res;
4037 bson_iter_t iter;
4038 bson_iter_t array_iter;
4039 double val;
4040
4041 command = BCON_NEW ("distinct",
4042 BCON_UTF8 (COLLECTION_NAME),
4043 "key",
4044 BCON_UTF8 ("x"),
4045 "query",
4046 "{",
4047 "x",
4048 "{",
4049 "$gt",
4050 BCON_DOUBLE (1.0),
4051 "}",
4052 "}");
4053 res =
4054 mongoc_database_command_simple (database, command, NULL, &reply, &error);
4055 if (!res) {
4056 fprintf (stderr, "Error with distinct: %s\n", error.message);
4057 goto cleanup;
4058 }
4059
4060 /* Do something with reply (in this case iterate through the values) */
4061 if (!(bson_iter_init_find (&iter, &reply, "values") &&
4062 BSON_ITER_HOLDS_ARRAY (&iter) &&
4063 bson_iter_recurse (&iter, &array_iter))) {
4064 fprintf (stderr, "Couldn't extract \"values\" field from response\n");
4065 goto cleanup;
4066 }
4067
4068 while (bson_iter_next (&array_iter)) {
4069 if (BSON_ITER_HOLDS_DOUBLE (&array_iter)) {
4070 val = bson_iter_double (&array_iter);
4071 printf ("Next double: %f\n", val);
4072 }
4073 }
4074
4075 cleanup:
4076 /* cleanup */
4077 bson_destroy (command);
4078 bson_destroy (&reply);
4079 return res;
4080 }
4081
4082
4083 "mapReduce" - basic example
4084 A simple example using the map reduce framework. It simply adds up the
4085 number of occurrences of each "tag".
4086
4087 First define the map and reduce functions:
4088
4089 constants.c
4090
4091 const char *const COLLECTION_NAME = "things";
4092
4093 /* Our map function just emits a single (key, 1) pair for each tag
4094 in the array: */
4095 const char *const MAPPER = "function () {"
4096 "this.tags.forEach(function(z) {"
4097 "emit(z, 1);"
4098 "});"
4099 "}";
4100
4101 /* The reduce function sums over all of the emitted values for a
4102 given key: */
4103 const char *const REDUCER = "function (key, values) {"
4104 "var total = 0;"
4105 "for (var i = 0; i < values.length; i++) {"
4106 "total += values[i];"
4107 "}"
4108 "return total;"
4109 "}";
4110 /* Note We can't just return values.length as the reduce function
4111 might be called iteratively on the results of other reduce
4112 steps. */
4113
4114
4115 Run the mapReduce command. Use the generic command helpers (e.g.
4116 mongoc_database_command_simple()). Do not the read command helpers
4117 (e.g. mongoc_database_read_command_with_opts()) because they are con‐
4118 sidered retryable read operations. If retryable reads are enabled,
4119 those operations will retry once on a retryable error, giving undesir‐
4120 able behavior for mapReduce.
4121
4122 map-reduce-basic.c
4123
4124 bool
4125 map_reduce_basic (mongoc_database_t *database)
4126 {
4127 bson_t reply;
4128 bson_t *command;
4129 bool res;
4130 bson_error_t error;
4131 mongoc_cursor_t *cursor;
4132 const bson_t *doc;
4133
4134 bool query_done = false;
4135
4136 const char *out_collection_name = "outCollection";
4137 mongoc_collection_t *out_collection;
4138
4139 /* Empty find query */
4140 bson_t find_query = BSON_INITIALIZER;
4141
4142 /* Construct the mapReduce command */
4143
4144 /* Other arguments can also be specified here, like "query" or
4145 "limit" and so on */
4146 command = BCON_NEW ("mapReduce",
4147 BCON_UTF8 (COLLECTION_NAME),
4148 "map",
4149 BCON_CODE (MAPPER),
4150 "reduce",
4151 BCON_CODE (REDUCER),
4152 "out",
4153 BCON_UTF8 (out_collection_name));
4154 res =
4155 mongoc_database_command_simple (database, command, NULL, &reply, &error);
4156
4157 if (!res) {
4158 fprintf (stderr, "MapReduce failed: %s\n", error.message);
4159 goto cleanup;
4160 }
4161
4162 /* Do something with the reply (it doesn't contain the mapReduce results) */
4163 print_res (&reply);
4164
4165 /* Now we'll query outCollection to see what the results are */
4166 out_collection =
4167 mongoc_database_get_collection (database, out_collection_name);
4168 cursor = mongoc_collection_find_with_opts (
4169 out_collection, &find_query, NULL, NULL);
4170 query_done = true;
4171
4172 /* Do something with the results */
4173 while (mongoc_cursor_next (cursor, &doc)) {
4174 print_res (doc);
4175 }
4176
4177 if (mongoc_cursor_error (cursor, &error)) {
4178 fprintf (stderr, "ERROR: %s\n", error.message);
4179 res = false;
4180 goto cleanup;
4181 }
4182
4183 cleanup:
4184 /* cleanup */
4185 if (query_done) {
4186 mongoc_cursor_destroy (cursor);
4187 mongoc_collection_destroy (out_collection);
4188 }
4189
4190 bson_destroy (&reply);
4191 bson_destroy (command);
4192
4193 return res;
4194 }
4195
4196
4197 "mapReduce" - more complicated example
4198 You must have replica set running for this.
4199
4200 In this example we contact a secondary in the replica set and do an
4201 "inline" map reduce, so the results are returned immediately:
4202
4203 map-reduce-advanced.c
4204
4205 bool
4206 map_reduce_advanced (mongoc_database_t *database)
4207 {
4208 bson_t *command;
4209 bson_error_t error;
4210 bool res = true;
4211 mongoc_cursor_t *cursor;
4212 mongoc_read_prefs_t *read_pref;
4213 const bson_t *doc;
4214
4215 /* Construct the mapReduce command */
4216 /* Other arguments can also be specified here, like "query" or "limit"
4217 and so on */
4218
4219 /* Read the results inline from a secondary replica */
4220 command = BCON_NEW ("mapReduce",
4221 BCON_UTF8 (COLLECTION_NAME),
4222 "map",
4223 BCON_CODE (MAPPER),
4224 "reduce",
4225 BCON_CODE (REDUCER),
4226 "out",
4227 "{",
4228 "inline",
4229 "1",
4230 "}");
4231
4232 read_pref = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
4233 cursor = mongoc_database_command (
4234 database, MONGOC_QUERY_NONE, 0, 0, 0, command, NULL, read_pref);
4235
4236 /* Do something with the results */
4237 while (mongoc_cursor_next (cursor, &doc)) {
4238 print_res (doc);
4239 }
4240
4241 if (mongoc_cursor_error (cursor, &error)) {
4242 fprintf (stderr, "ERROR: %s\n", error.message);
4243 res = false;
4244 }
4245
4246 mongoc_cursor_destroy (cursor);
4247 mongoc_read_prefs_destroy (read_pref);
4248 bson_destroy (command);
4249
4250 return res;
4251 }
4252
4253
4254 Running the Examples
4255 Here's how to run the example code
4256
4257 basic-aggregation.c
4258
4259 /*
4260 * Copyright 2016 MongoDB, Inc.
4261 *
4262 * Licensed under the Apache License, Version 2.0 (the "License");
4263 * you may not use this file except in compliance with the License.
4264 * You may obtain a copy of the License at
4265 *
4266 * http://www.apache.org/licenses/LICENSE-2.0
4267 *
4268 * Unless required by applicable law or agreed to in writing, software
4269 * distributed under the License is distributed on an "AS IS" BASIS,
4270 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4271 * See the License for the specific language governing permissions and
4272 * limitations under the License.
4273 */
4274
4275
4276 #include <mongoc/mongoc.h>
4277 #include <stdio.h>
4278
4279
4280 #include "constants.c"
4281
4282 #include "../doc-common-insert.c"
4283 #include "distinct.c"
4284 #include "map-reduce-basic.c"
4285 #include "map-reduce-advanced.c"
4286
4287
4288 int
4289 main (int argc, char *argv[])
4290 {
4291 mongoc_database_t *database = NULL;
4292 mongoc_client_t *client = NULL;
4293 mongoc_collection_t *collection = NULL;
4294 mongoc_uri_t *uri = NULL;
4295 bson_error_t error;
4296 char *host_and_port = NULL;
4297 int exit_code = EXIT_FAILURE;
4298
4299 if (argc != 2) {
4300 fprintf (stderr, "usage: %s CONNECTION-STRING\n", argv[0]);
4301 fprintf (stderr,
4302 "the connection string can be of the following forms:\n");
4303 fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
4304 fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
4305 fprintf (stderr,
4306 "mongodb://user:pass@localhost:27017\t"
4307 "local machine on port 27017, and authenticate with username "
4308 "user and password pass\n");
4309 return exit_code;
4310 }
4311
4312 mongoc_init ();
4313
4314 if (strncmp (argv[1], "mongodb://", 10) == 0) {
4315 host_and_port = bson_strdup (argv[1]);
4316 } else {
4317 host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
4318 }
4319
4320 uri = mongoc_uri_new_with_error (host_and_port, &error);
4321 if (!uri) {
4322 fprintf (stderr,
4323 "failed to parse URI: %s\n"
4324 "error message: %s\n",
4325 host_and_port,
4326 error.message);
4327 goto cleanup;
4328 }
4329
4330 client = mongoc_client_new_from_uri (uri);
4331 if (!client) {
4332 goto cleanup;
4333 }
4334
4335 mongoc_client_set_error_api (client, 2);
4336 database = mongoc_client_get_database (client, "test");
4337 collection = mongoc_database_get_collection (database, COLLECTION_NAME);
4338
4339 printf ("Inserting data\n");
4340 if (!insert_data (collection)) {
4341 goto cleanup;
4342 }
4343
4344 printf ("distinct\n");
4345 if (!distinct (database)) {
4346 goto cleanup;
4347 }
4348
4349 printf ("map reduce\n");
4350 if (!map_reduce_basic (database)) {
4351 goto cleanup;
4352 }
4353
4354 printf ("more complicated map reduce\n");
4355 if (!map_reduce_advanced (database)) {
4356 goto cleanup;
4357 }
4358
4359 exit_code = EXIT_SUCCESS;
4360
4361 cleanup:
4362 if (collection) {
4363 mongoc_collection_destroy (collection);
4364 }
4365
4366 if (database) {
4367 mongoc_database_destroy (database);
4368 }
4369
4370 if (client) {
4371 mongoc_client_destroy (client);
4372 }
4373
4374 if (uri) {
4375 mongoc_uri_destroy (uri);
4376 }
4377
4378 if (host_and_port) {
4379 bson_free (host_and_port);
4380 }
4381
4382 mongoc_cleanup ();
4383 return exit_code;
4384 }
4385
4386
4387 If you want to try the advanced map reduce example with a secondary,
4388 start a replica set (instructions for how to do this can be found
4389 here).
4390
4391 Otherwise, just start an instance of MongoDB:
4392
4393 $ mongod
4394
4395 Now compile and run the example program:
4396
4397 $ cd examples/basic_aggregation/
4398 $ gcc -Wall -o agg-example basic-aggregation.c $(pkg-config --cflags --libs libmongoc-1.0)
4399 $ ./agg-example localhost
4400
4401 Inserting data
4402 distinct
4403 Next double: 2.000000
4404 Next double: 3.000000
4405 map reduce
4406 { "result" : "outCollection", "timeMillis" : 155, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 }
4407 { "_id" : "cat", "value" : 63 }
4408 { "_id" : "dog", "value" : 42 }
4409 { "_id" : "mouse", "value" : 21 }
4410 more complicated map reduce
4411 { "results" : [ { "_id" : "cat", "value" : 63 }, { "_id" : "dog", "value" : 42 }, { "_id" : "mouse", "value" : 21 } ], "timeMillis" : 14, "counts" : { "input" : 84, "emit" : 126, "reduce" : 3, "output" : 3 }, "ok" : 1 }
4412
4413 Using libmongoc in a Microsoft Visual Studio project
4414 Download and install libmongoc on your system, then open Visual Studio,
4415 select "File→New→Project...", and create a new Win32 Console Applica‐
4416 tion. [image]
4417
4418 Remember to switch the platform from 32-bit to 64-bit: [image]
4419
4420 Right-click on your console application in the Solution Explorer and
4421 select "Properties". Choose to edit properties for "All Configura‐
4422 tions", expand the "C/C++" options and choose "General". Add to the
4423 "Additional Include Directories" these paths:
4424
4425 C:\mongo-c-driver\include\libbson-1.0
4426 C:\mongo-c-driver\include\libmongoc-1.0
4427 [image]
4428
4429 (If you chose a different CMAKE_INSTALL_PREFIX when you ran CMake, your
4430 include paths will be different.)
4431
4432 Also in the Properties dialog, expand the "Linker" options and choose
4433 "Input", and add to the "Additional Dependencies" these libraries:
4434
4435 C:\mongo-c-driver\lib\bson-1.0.lib
4436 C:\mongo-c-driver\lib\mongoc-1.0.lib
4437 [image]
4438
4439 Adding these libraries as dependencies provides linker symbols to build
4440 your application, but to actually run it, libbson's and libmongoc's
4441 DLLs must be in your executable path. Select "Debugging" in the Proper‐
4442 ties dialog, and set the "Environment" option to:
4443
4444 PATH=c:/mongo-c-driver/bin
4445 [image]
4446
4447 Finally, include "mongoc/mongoc.h" in your project's "stdafx.h":
4448
4449 #include <mongoc/mongoc.h>
4450
4451 Static linking
4452 Following the instructions above, you have dynamically linked your ap‐
4453 plication to the libbson and libmongoc DLLs. This is usually the right
4454 choice. If you want to link statically instead, update your "Additional
4455 Dependencies" list by removing bson-1.0.lib and mongoc-1.0.lib and re‐
4456 placing them with these libraries:
4457
4458 C:\mongo-c-driver\lib\bson-static-1.0.lib
4459 C:\mongo-c-driver\lib\mongoc-static-1.0.lib
4460 ws2_32.lib
4461 Secur32.lib
4462 Crypt32.lib
4463 BCrypt.lib
4464 [image]
4465
4466 (To explain the purpose of each library: bson-static-1.0.lib and mon‐
4467 goc-static-1.0.lib are static archives of the driver code. The socket
4468 library ws2_32 is required by libbson, which uses the socket routine
4469 gethostname to help guarantee ObjectId uniqueness. The BCrypt library
4470 is used by libmongoc for TLS connections to MongoDB, and Secur32 and
4471 Crypt32 are required for enterprise authentication methods like Ker‐
4472 beros.)
4473
4474 Finally, define two preprocessor symbols before including mongoc/mon‐
4475 goc.h in your stdafx.h:
4476
4477 #define BSON_STATIC
4478 #define MONGOC_STATIC
4479 #include <mongoc/mongoc.h>
4480
4481 Making these changes to your project is only required for static link‐
4482 ing; for most people, the dynamic-linking instructions above are pre‐
4483 ferred.
4484
4485 Next Steps
4486 Now you can build and debug applications in Visual Studio that use
4487 libbson and libmongoc. Proceed to Making a Connection in the tutorial
4488 to learn how connect to MongoDB and perform operations.
4489
4490 Manage Collection Indexes
4491 To create indexes on a MongoDB collection, use
4492 mongoc_collection_create_indexes_with_opts():
4493
4494 // `keys` represents an ascending index on field `x`.
4495 bson_t *keys = BCON_NEW ("x", BCON_INT32 (1));
4496 mongoc_index_model_t *im = mongoc_index_model_new (keys, NULL /* opts */);
4497 if (mongoc_collection_create_indexes_with_opts (
4498 coll, &im, 1, NULL /* opts */, NULL /* reply */, &error)) {
4499 printf ("Successfully created index\n");
4500 } else {
4501 bson_destroy (keys);
4502 HANDLE_ERROR ("Failed to create index: %s", error.message);
4503 }
4504 bson_destroy (keys);
4505
4506
4507 To list indexes, use mongoc_collection_find_indexes_with_opts():
4508
4509 mongoc_cursor_t *cursor =
4510 mongoc_collection_find_indexes_with_opts (coll, NULL /* opts */);
4511 printf ("Listing indexes:\n");
4512 const bson_t *got;
4513 while (mongoc_cursor_next (cursor, &got)) {
4514 char *got_str = bson_as_canonical_extended_json (got, NULL);
4515 printf (" %s\n", got_str);
4516 bson_free (got_str);
4517 }
4518 if (mongoc_cursor_error (cursor, &error)) {
4519 mongoc_cursor_destroy (cursor);
4520 HANDLE_ERROR ("Failed to list indexes: %s", error.message);
4521 }
4522 mongoc_cursor_destroy (cursor);
4523
4524
4525 To drop an index, use mongoc_collection_drop_index_with_opts(). The in‐
4526 dex name may be obtained from the keys document with
4527 mongoc_collection_keys_to_index_string():
4528
4529 bson_t *keys = BCON_NEW ("x", BCON_INT32 (1));
4530 char *index_name = mongoc_collection_keys_to_index_string (keys);
4531 if (mongoc_collection_drop_index_with_opts (
4532 coll, index_name, NULL /* opts */, &error)) {
4533 printf ("Successfully dropped index\n");
4534 } else {
4535 bson_free (index_name);
4536 bson_destroy (keys);
4537 HANDLE_ERROR ("Failed to drop index: %s", error.message);
4538 }
4539 bson_free (index_name);
4540 bson_destroy (keys);
4541
4542
4543 For a full example, see example-manage-collection-indexes.c.
4544
4545 Aids for Debugging
4546 GDB
4547 This repository contains a .gdbinit file that contains helper functions
4548 to aid debugging of data structures. GDB will load this file
4549 automatically if you have added the directory which contains the
4550 .gdbinit file to GDB's auto-load safe-path, and you start GDB from the
4551 directory which holds the .gdbinit file.
4552
4553 You can see the safe-path with show auto-load safe-path on a GDB
4554 prompt. You can configure it by setting it in ~/.gdbinit with:
4555
4556 add-auto-load-safe-path /path/to/mongo-c-driver
4557
4558 If you haven't added the path to your auto-load safe-path, or start GDB
4559 in another directory, load the file with:
4560
4561 source path/to/mongo-c-driver/.gdbinit
4562
4563 The .gdbinit file defines the printbson function, which shows the con‐
4564 tents of a bson_t * variable. If you have a local bson_t, then you
4565 must prefix the variable with a &.
4566
4567 An example GDB session looks like:
4568
4569 (gdb) printbson bson
4570 ALLOC [0x555556cd7310 + 0] (len=475)
4571 {
4572 'bool' : true,
4573 'int32' : NumberInt("42"),
4574 'int64' : NumberLong("3000000042"),
4575 'string' : "Stŕìñg",
4576 'objectId' : ObjectID("5A1442F3122D331C3C6757E1"),
4577 'utcDateTime' : UTCDateTime(1511277299031),
4578 'arrayOfInts' : [
4579 '0' : NumberInt("1"),
4580 '1' : NumberInt("2")
4581 ],
4582 'embeddedDocument' : {
4583 'arrayOfStrings' : [
4584 '0' : "one",
4585 '1' : "two"
4586 ],
4587 'double' : 2.718280,
4588 'notherDoc' : {
4589 'true' : NumberInt("1"),
4590 'false' : false
4591 }
4592 },
4593 'binary' : Binary("02", "3031343532333637"),
4594 'regex' : Regex("@[a-z]+@", "im"),
4595 'null' : null,
4596 'js' : JavaScript("print foo"),
4597 'jsws' : JavaScript("print foo") with scope: {
4598 'f' : NumberInt("42"),
4599 'a' : [
4600 '0' : 3.141593,
4601 '1' : 2.718282
4602 ]
4603 },
4604 'timestamp' : Timestamp(4294967295, 4294967295),
4605 'double' : 3.141593
4606 }
4607
4608 LLDB
4609 The mongo-c-driver repository contains a script lldb_bson.py that can
4610 be imported into an LLDB sessions and allows rich inspection of BSON
4611 values.
4612
4613 NOTE:
4614 The lldb_bson.py module requires an LLDB with Python 3.8 or newer.
4615
4616 To activate the script, import it from the LLDB command line:
4617
4618 (lldb) command script import /path/to/mongo-c-driver/lldb_bson.py
4619
4620 Upon success, the message lldb_bson is ready will be printed to the
4621 LLDB console.
4622
4623 The import of this script can be made automatic by adding the command
4624 to an .lldbinit file. For example: Create a file ~/.lldbinit contain‐
4625 ing:
4626
4627 command script import /path/to/mongo-c-driver/lldb_bson.py
4628
4629 The docstring at the top of the lldb_bson.py file contains more infor‐
4630 mation on the capabilities of the module.
4631
4632 Debug assertions
4633 To enable runtime debug assertions, configure with -DENABLE_DEBUG_AS‐
4634 SERTIONS=ON.
4635
4636 In-Use Encryption
4637 In-Use Encryption consists of two features:
4638
4639 Client-Side Field Level Encryption
4640 New in MongoDB 4.2, Client-Side Field Level Encryption (also referred
4641 to as CSFLE) allows administrators and developers to encrypt specific
4642 data fields in addition to other MongoDB encryption features.
4643
4644 With CSFLE, developers can encrypt fields client side without any
4645 server-side configuration or directives. CSFLE supports workloads where
4646 applications must guarantee that unauthorized parties, including server
4647 administrators, cannot read the encrypted data.
4648
4649 Automatic encryption, where sensitive fields in commands are encrypted
4650 automatically, requires an Enterprise-only dependency for Query Analy‐
4651 sis. See In-Use Encryption for more information.
4652
4653 SEE ALSO:
4654 The MongoDB Manual for Client-Side Field Level Encryption
4655
4656
4657 Automatic Client-Side Field Level Encryption
4658 Automatic encryption is enabled by calling
4659 mongoc_client_enable_auto_encryption() on a mongoc_client_t. The fol‐
4660 lowing examples show how to set up automatic encryption using
4661 mongoc_client_encryption_t to create a new encryption data key.
4662
4663 NOTE:
4664 Automatic encryption requires MongoDB 4.2 enterprise or a MongoDB
4665 4.2 Atlas cluster. The community version of the server supports au‐
4666 tomatic decryption as well as Explicit Encryption.
4667
4668 Providing Local Automatic Encryption Rules
4669 The following example shows how to specify automatic encryption rules
4670 using a schema map set with
4671 mongoc_auto_encryption_opts_set_schema_map(). The automatic encryption
4672 rules are expressed using a strict subset of the JSON Schema syntax.
4673
4674 Supplying a schema map provides more security than relying on JSON
4675 Schemas obtained from the server. It protects against a malicious
4676 server advertising a false JSON Schema, which could trick the client
4677 into sending unencrypted data that should be encrypted.
4678
4679 JSON Schemas supplied in the schema map only apply to configuring auto‐
4680 matic encryption. Other validation rules in the JSON schema will not be
4681 enforced by the driver and will result in an error:
4682
4683 client-side-encryption-schema-map.c
4684
4685 #include <mongoc/mongoc.h>
4686 #include <stdio.h>
4687 #include <stdlib.h>
4688
4689 #include "client-side-encryption-helpers.h"
4690
4691 /* Helper method to create a new data key in the key vault, a schema to use that
4692 * key, and writes the schema to a file for later use. */
4693 static bool
4694 create_schema_file (bson_t *kms_providers,
4695 const char *keyvault_db,
4696 const char *keyvault_coll,
4697 mongoc_client_t *keyvault_client,
4698 bson_error_t *error)
4699 {
4700 mongoc_client_encryption_t *client_encryption = NULL;
4701 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
4702 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
4703 bson_value_t datakey_id = {0};
4704 char *keyaltnames[] = {"mongoc_encryption_example_1"};
4705 bson_t *schema = NULL;
4706 char *schema_string = NULL;
4707 size_t schema_string_len;
4708 FILE *outfile = NULL;
4709 bool ret = false;
4710
4711 client_encryption_opts = mongoc_client_encryption_opts_new ();
4712 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
4713 kms_providers);
4714 mongoc_client_encryption_opts_set_keyvault_namespace (
4715 client_encryption_opts, keyvault_db, keyvault_coll);
4716 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
4717 keyvault_client);
4718
4719 client_encryption =
4720 mongoc_client_encryption_new (client_encryption_opts, error);
4721 if (!client_encryption) {
4722 goto fail;
4723 }
4724
4725 /* Create a new data key and json schema for the encryptedField.
4726 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
4727 */
4728 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
4729 mongoc_client_encryption_datakey_opts_set_keyaltnames (
4730 datakey_opts, keyaltnames, 1);
4731 if (!mongoc_client_encryption_create_datakey (
4732 client_encryption, "local", datakey_opts, &datakey_id, error)) {
4733 goto fail;
4734 }
4735
4736 /* Create a schema describing that "encryptedField" is a string encrypted
4737 * with the newly created data key using deterministic encryption. */
4738 schema = BCON_NEW ("properties",
4739 "{",
4740 "encryptedField",
4741 "{",
4742 "encrypt",
4743 "{",
4744 "keyId",
4745 "[",
4746 BCON_BIN (datakey_id.value.v_binary.subtype,
4747 datakey_id.value.v_binary.data,
4748 datakey_id.value.v_binary.data_len),
4749 "]",
4750 "bsonType",
4751 "string",
4752 "algorithm",
4753 MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
4754 "}",
4755 "}",
4756 "}",
4757 "bsonType",
4758 "object");
4759
4760 /* Use canonical JSON so that other drivers and tools will be
4761 * able to parse the MongoDB extended JSON file. */
4762 schema_string = bson_as_canonical_extended_json (schema, &schema_string_len);
4763 outfile = fopen ("jsonSchema.json", "w");
4764 if (0 == fwrite (schema_string, sizeof (char), schema_string_len, outfile)) {
4765 fprintf (stderr, "failed to write to file\n");
4766 goto fail;
4767 }
4768
4769 ret = true;
4770 fail:
4771 mongoc_client_encryption_destroy (client_encryption);
4772 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
4773 mongoc_client_encryption_opts_destroy (client_encryption_opts);
4774 bson_free (schema_string);
4775 bson_destroy (schema);
4776 bson_value_destroy (&datakey_id);
4777 if (outfile) {
4778 fclose (outfile);
4779 }
4780 return ret;
4781 }
4782
4783 /* This example demonstrates how to use automatic encryption with a client-side
4784 * schema map using the enterprise version of MongoDB */
4785 int
4786 main (void)
4787 {
4788 /* The collection used to store the encryption data keys. */
4789 #define KEYVAULT_DB "encryption"
4790 #define KEYVAULT_COLL "__libmongocTestKeyVault"
4791 /* The collection used to store the encrypted documents in this example. */
4792 #define ENCRYPTED_DB "test"
4793 #define ENCRYPTED_COLL "coll"
4794
4795 int exit_status = EXIT_FAILURE;
4796 bool ret;
4797 uint8_t *local_masterkey = NULL;
4798 uint32_t local_masterkey_len;
4799 bson_t *kms_providers = NULL;
4800 bson_error_t error = {0};
4801 bson_t *index_keys = NULL;
4802 bson_t *index_opts = NULL;
4803 mongoc_index_model_t *index_model = NULL;
4804 bson_json_reader_t *reader = NULL;
4805 bson_t schema = BSON_INITIALIZER;
4806 bson_t *schema_map = NULL;
4807
4808 /* The MongoClient used to access the key vault (keyvault_namespace). */
4809 mongoc_client_t *keyvault_client = NULL;
4810 mongoc_collection_t *keyvault_coll = NULL;
4811 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
4812 mongoc_client_t *client = NULL;
4813 mongoc_collection_t *coll = NULL;
4814 bson_t *to_insert = NULL;
4815 mongoc_client_t *unencrypted_client = NULL;
4816 mongoc_collection_t *unencrypted_coll = NULL;
4817
4818 mongoc_init ();
4819
4820 /* Configure the master key. This must be the same master key that was used
4821 * to create the encryption key. */
4822 local_masterkey =
4823 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
4824 if (!local_masterkey || local_masterkey_len != 96) {
4825 fprintf (stderr,
4826 "Specify LOCAL_MASTERKEY environment variable as a "
4827 "secure random 96 byte hex value.\n");
4828 goto fail;
4829 }
4830
4831 kms_providers = BCON_NEW ("local",
4832 "{",
4833 "key",
4834 BCON_BIN (0, local_masterkey, local_masterkey_len),
4835 "}");
4836
4837 /* Set up the key vault for this example. */
4838 keyvault_client = mongoc_client_new (
4839 "mongodb://localhost/?appname=client-side-encryption-keyvault");
4840 BSON_ASSERT (keyvault_client);
4841
4842 keyvault_coll = mongoc_client_get_collection (
4843 keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
4844 mongoc_collection_drop (keyvault_coll, NULL);
4845
4846 /* Create a unique index to ensure that two data keys cannot share the same
4847 * keyAltName. This is recommended practice for the key vault. */
4848 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
4849 index_opts = BCON_NEW ("unique",
4850 BCON_BOOL (true),
4851 "partialFilterExpression",
4852 "{",
4853 "keyAltNames",
4854 "{",
4855 "$exists",
4856 BCON_BOOL (true),
4857 "}",
4858 "}");
4859 index_model = mongoc_index_model_new (index_keys, index_opts);
4860 ret = mongoc_collection_create_indexes_with_opts (keyvault_coll,
4861 &index_model,
4862 1,
4863 NULL /* opts */,
4864 NULL /* reply */,
4865 &error);
4866
4867 if (!ret) {
4868 goto fail;
4869 }
4870
4871 /* Create a new data key and a schema using it for encryption. Save the
4872 * schema to the file jsonSchema.json */
4873 ret = create_schema_file (
4874 kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
4875
4876 if (!ret) {
4877 goto fail;
4878 }
4879
4880 /* Load the JSON Schema and construct the local schema_map option. */
4881 reader = bson_json_reader_new_from_file ("jsonSchema.json", &error);
4882 if (!reader) {
4883 goto fail;
4884 }
4885
4886 bson_json_reader_read (reader, &schema, &error);
4887
4888 /* Construct the schema map, mapping the namespace of the collection to the
4889 * schema describing encryption. */
4890 schema_map =
4891 BCON_NEW (ENCRYPTED_DB "." ENCRYPTED_COLL, BCON_DOCUMENT (&schema));
4892
4893 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
4894 mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts,
4895 keyvault_client);
4896 mongoc_auto_encryption_opts_set_keyvault_namespace (
4897 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
4898 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
4899 kms_providers);
4900 mongoc_auto_encryption_opts_set_schema_map (auto_encryption_opts,
4901 schema_map);
4902
4903 client =
4904 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
4905 BSON_ASSERT (client);
4906
4907 /* Enable automatic encryption. It will determine that encryption is
4908 * necessary from the schema map instead of relying on the server to provide
4909 * a schema. */
4910 ret = mongoc_client_enable_auto_encryption (
4911 client, auto_encryption_opts, &error);
4912 if (!ret) {
4913 goto fail;
4914 }
4915
4916 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
4917
4918 /* Clear old data */
4919 mongoc_collection_drop (coll, NULL);
4920
4921 to_insert = BCON_NEW ("encryptedField", "123456789");
4922 ret = mongoc_collection_insert_one (
4923 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
4924 if (!ret) {
4925 goto fail;
4926 }
4927 printf ("decrypted document: ");
4928 if (!print_one_document (coll, &error)) {
4929 goto fail;
4930 }
4931 printf ("\n");
4932
4933 unencrypted_client = mongoc_client_new (
4934 "mongodb://localhost/?appname=client-side-encryption-unencrypted");
4935 BSON_ASSERT (unencrypted_client);
4936
4937 unencrypted_coll = mongoc_client_get_collection (
4938 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
4939 printf ("encrypted document: ");
4940 if (!print_one_document (unencrypted_coll, &error)) {
4941 goto fail;
4942 }
4943 printf ("\n");
4944
4945 exit_status = EXIT_SUCCESS;
4946 fail:
4947 if (error.code) {
4948 fprintf (stderr, "error: %s\n", error.message);
4949 }
4950
4951 bson_free (local_masterkey);
4952 bson_destroy (kms_providers);
4953 mongoc_collection_destroy (keyvault_coll);
4954 mongoc_index_model_destroy (index_model);
4955 bson_destroy (index_opts);
4956 bson_destroy (index_keys);
4957 bson_json_reader_destroy (reader);
4958 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
4959 mongoc_collection_destroy (coll);
4960 mongoc_client_destroy (client);
4961 bson_destroy (to_insert);
4962 mongoc_collection_destroy (unencrypted_coll);
4963 mongoc_client_destroy (unencrypted_client);
4964 mongoc_client_destroy (keyvault_client);
4965 bson_destroy (&schema);
4966 bson_destroy (schema_map);
4967 mongoc_cleanup ();
4968 return exit_status;
4969 }
4970
4971
4972 Server-Side Field Level Encryption Enforcement
4973 The MongoDB 4.2 server supports using schema validation to enforce en‐
4974 cryption of specific fields in a collection. This schema validation
4975 will prevent an application from inserting unencrypted values for any
4976 fields marked with the "encrypt" JSON schema keyword.
4977
4978 The following example shows how to set up automatic encryption using
4979 mongoc_client_encryption_t to create a new encryption data key and cre‐
4980 ate a collection with the necessary JSON Schema:
4981
4982 client-side-encryption-server-schema.c
4983
4984 #include <mongoc/mongoc.h>
4985 #include <stdio.h>
4986 #include <stdlib.h>
4987
4988 #include "client-side-encryption-helpers.h"
4989
4990 /* Helper method to create and return a JSON schema to use for encryption.
4991 The caller will use the returned schema for server-side encryption validation.
4992 */
4993 static bson_t *
4994 create_schema (bson_t *kms_providers,
4995 const char *keyvault_db,
4996 const char *keyvault_coll,
4997 mongoc_client_t *keyvault_client,
4998 bson_error_t *error)
4999 {
5000 mongoc_client_encryption_t *client_encryption = NULL;
5001 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5002 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5003 bson_value_t datakey_id = {0};
5004 char *keyaltnames[] = {"mongoc_encryption_example_2"};
5005 bson_t *schema = NULL;
5006
5007 client_encryption_opts = mongoc_client_encryption_opts_new ();
5008 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5009 kms_providers);
5010 mongoc_client_encryption_opts_set_keyvault_namespace (
5011 client_encryption_opts, keyvault_db, keyvault_coll);
5012 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5013 keyvault_client);
5014
5015 client_encryption =
5016 mongoc_client_encryption_new (client_encryption_opts, error);
5017 if (!client_encryption) {
5018 goto fail;
5019 }
5020
5021 /* Create a new data key and json schema for the encryptedField.
5022 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5023 */
5024 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5025 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5026 datakey_opts, keyaltnames, 1);
5027 if (!mongoc_client_encryption_create_datakey (
5028 client_encryption, "local", datakey_opts, &datakey_id, error)) {
5029 goto fail;
5030 }
5031
5032 /* Create a schema describing that "encryptedField" is a string encrypted
5033 * with the newly created data key using deterministic encryption. */
5034 schema = BCON_NEW ("properties",
5035 "{",
5036 "encryptedField",
5037 "{",
5038 "encrypt",
5039 "{",
5040 "keyId",
5041 "[",
5042 BCON_BIN (datakey_id.value.v_binary.subtype,
5043 datakey_id.value.v_binary.data,
5044 datakey_id.value.v_binary.data_len),
5045 "]",
5046 "bsonType",
5047 "string",
5048 "algorithm",
5049 MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
5050 "}",
5051 "}",
5052 "}",
5053 "bsonType",
5054 "object");
5055
5056 fail:
5057 mongoc_client_encryption_destroy (client_encryption);
5058 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5059 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5060 bson_value_destroy (&datakey_id);
5061 return schema;
5062 }
5063
5064 /* This example demonstrates how to use automatic encryption with a server-side
5065 * schema using the enterprise version of MongoDB */
5066 int
5067 main (void)
5068 {
5069 /* The collection used to store the encryption data keys. */
5070 #define KEYVAULT_DB "encryption"
5071 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5072 /* The collection used to store the encrypted documents in this example. */
5073 #define ENCRYPTED_DB "test"
5074 #define ENCRYPTED_COLL "coll"
5075
5076 int exit_status = EXIT_FAILURE;
5077 bool ret;
5078 uint8_t *local_masterkey = NULL;
5079 uint32_t local_masterkey_len;
5080 bson_t *kms_providers = NULL;
5081 bson_error_t error = {0};
5082 bson_t *index_keys = NULL;
5083 bson_t *index_opts = NULL;
5084 mongoc_index_model_t *index_model = NULL;
5085 bson_json_reader_t *reader = NULL;
5086 bson_t *schema = NULL;
5087
5088 /* The MongoClient used to access the key vault (keyvault_namespace). */
5089 mongoc_client_t *keyvault_client = NULL;
5090 mongoc_collection_t *keyvault_coll = NULL;
5091 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
5092 mongoc_client_t *client = NULL;
5093 mongoc_collection_t *coll = NULL;
5094 bson_t *to_insert = NULL;
5095 mongoc_client_t *unencrypted_client = NULL;
5096 mongoc_collection_t *unencrypted_coll = NULL;
5097 bson_t *create_cmd = NULL;
5098 bson_t *create_cmd_opts = NULL;
5099 mongoc_write_concern_t *wc = NULL;
5100
5101 mongoc_init ();
5102
5103 /* Configure the master key. This must be the same master key that was used
5104 * to create
5105 * the encryption key. */
5106 local_masterkey =
5107 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5108 if (!local_masterkey || local_masterkey_len != 96) {
5109 fprintf (stderr,
5110 "Specify LOCAL_MASTERKEY environment variable as a "
5111 "secure random 96 byte hex value.\n");
5112 goto fail;
5113 }
5114
5115 kms_providers = BCON_NEW ("local",
5116 "{",
5117 "key",
5118 BCON_BIN (0, local_masterkey, local_masterkey_len),
5119 "}");
5120
5121 /* Set up the key vault for this example. */
5122 keyvault_client = mongoc_client_new (
5123 "mongodb://localhost/?appname=client-side-encryption-keyvault");
5124 BSON_ASSERT (keyvault_client);
5125
5126 keyvault_coll = mongoc_client_get_collection (
5127 keyvault_client, KEYVAULT_DB, KEYVAULT_COLL);
5128 mongoc_collection_drop (keyvault_coll, NULL);
5129
5130 /* Create a unique index to ensure that two data keys cannot share the same
5131 * keyAltName. This is recommended practice for the key vault. */
5132 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5133 index_opts = BCON_NEW ("unique",
5134 BCON_BOOL (true),
5135 "partialFilterExpression",
5136 "{",
5137 "keyAltNames",
5138 "{",
5139 "$exists",
5140 BCON_BOOL (true),
5141 "}",
5142 "}");
5143 index_model = mongoc_index_model_new (index_keys, index_opts);
5144 ret = mongoc_collection_create_indexes_with_opts (keyvault_coll,
5145 &index_model,
5146 1,
5147 NULL /* opts */,
5148 NULL /* reply */,
5149 &error);
5150
5151 if (!ret) {
5152 goto fail;
5153 }
5154
5155 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
5156 mongoc_auto_encryption_opts_set_keyvault_client (auto_encryption_opts,
5157 keyvault_client);
5158 mongoc_auto_encryption_opts_set_keyvault_namespace (
5159 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5160 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
5161 kms_providers);
5162 schema = create_schema (
5163 kms_providers, KEYVAULT_DB, KEYVAULT_COLL, keyvault_client, &error);
5164
5165 if (!schema) {
5166 goto fail;
5167 }
5168
5169 client =
5170 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5171 BSON_ASSERT (client);
5172
5173 ret = mongoc_client_enable_auto_encryption (
5174 client, auto_encryption_opts, &error);
5175 if (!ret) {
5176 goto fail;
5177 }
5178
5179 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5180
5181 /* Clear old data */
5182 mongoc_collection_drop (coll, NULL);
5183
5184 /* Create the collection with the encryption JSON Schema. */
5185 create_cmd = BCON_NEW ("create",
5186 ENCRYPTED_COLL,
5187 "validator",
5188 "{",
5189 "$jsonSchema",
5190 BCON_DOCUMENT (schema),
5191 "}");
5192 wc = mongoc_write_concern_new ();
5193 mongoc_write_concern_set_wmajority (wc, 0);
5194 create_cmd_opts = bson_new ();
5195 mongoc_write_concern_append (wc, create_cmd_opts);
5196 ret = mongoc_client_command_with_opts (client,
5197 ENCRYPTED_DB,
5198 create_cmd,
5199 NULL /* read prefs */,
5200 create_cmd_opts,
5201 NULL /* reply */,
5202 &error);
5203 if (!ret) {
5204 goto fail;
5205 }
5206
5207 to_insert = BCON_NEW ("encryptedField", "123456789");
5208 ret = mongoc_collection_insert_one (
5209 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5210 if (!ret) {
5211 goto fail;
5212 }
5213 printf ("decrypted document: ");
5214 if (!print_one_document (coll, &error)) {
5215 goto fail;
5216 }
5217 printf ("\n");
5218
5219 unencrypted_client = mongoc_client_new (
5220 "mongodb://localhost/?appname=client-side-encryption-unencrypted");
5221 BSON_ASSERT (unencrypted_client);
5222
5223 unencrypted_coll = mongoc_client_get_collection (
5224 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
5225 printf ("encrypted document: ");
5226 if (!print_one_document (unencrypted_coll, &error)) {
5227 goto fail;
5228 }
5229 printf ("\n");
5230
5231 /* Expect a server-side error if inserting with the unencrypted collection.
5232 */
5233 ret = mongoc_collection_insert_one (
5234 unencrypted_coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5235 if (!ret) {
5236 printf ("insert with unencrypted collection failed: %s\n", error.message);
5237 memset (&error, 0, sizeof (error));
5238 }
5239
5240 exit_status = EXIT_SUCCESS;
5241 fail:
5242 if (error.code) {
5243 fprintf (stderr, "error: %s\n", error.message);
5244 }
5245
5246 bson_free (local_masterkey);
5247 bson_destroy (kms_providers);
5248 mongoc_collection_destroy (keyvault_coll);
5249 mongoc_index_model_destroy (index_model);
5250 bson_destroy (index_opts);
5251 bson_destroy (index_keys);
5252 bson_json_reader_destroy (reader);
5253 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
5254 mongoc_collection_destroy (coll);
5255 mongoc_client_destroy (client);
5256 bson_destroy (to_insert);
5257 mongoc_collection_destroy (unencrypted_coll);
5258 mongoc_client_destroy (unencrypted_client);
5259 mongoc_client_destroy (keyvault_client);
5260 bson_destroy (schema);
5261 bson_destroy (create_cmd);
5262 bson_destroy (create_cmd_opts);
5263 mongoc_write_concern_destroy (wc);
5264
5265 mongoc_cleanup ();
5266 return exit_status;
5267 }
5268
5269
5270 Explicit Encryption
5271 Explicit encryption is a MongoDB community feature and does not use
5272 Query Analysis (mongocryptd or crypt_shared). Explicit encryption is
5273 provided by the mongoc_client_encryption_t class, for example:
5274
5275 client-side-encryption-explicit.c
5276
5277 #include <mongoc/mongoc.h>
5278 #include <stdio.h>
5279 #include <stdlib.h>
5280
5281 #include "client-side-encryption-helpers.h"
5282
5283 /* This example demonstrates how to use explicit encryption and decryption using
5284 * the community version of MongoDB */
5285 int
5286 main (void)
5287 {
5288 /* The collection used to store the encryption data keys. */
5289 #define KEYVAULT_DB "encryption"
5290 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5291 /* The collection used to store the encrypted documents in this example. */
5292 #define ENCRYPTED_DB "test"
5293 #define ENCRYPTED_COLL "coll"
5294
5295 int exit_status = EXIT_FAILURE;
5296 bool ret;
5297 uint8_t *local_masterkey = NULL;
5298 uint32_t local_masterkey_len;
5299 bson_t *kms_providers = NULL;
5300 bson_error_t error = {0};
5301 bson_t *index_keys = NULL;
5302 bson_t *index_opts = NULL;
5303 mongoc_index_model_t *index_model = NULL;
5304 bson_t *schema = NULL;
5305 mongoc_client_t *client = NULL;
5306 mongoc_collection_t *coll = NULL;
5307 mongoc_collection_t *keyvault_coll = NULL;
5308 bson_t *to_insert = NULL;
5309 bson_t *create_cmd = NULL;
5310 bson_t *create_cmd_opts = NULL;
5311 mongoc_write_concern_t *wc = NULL;
5312 mongoc_client_encryption_t *client_encryption = NULL;
5313 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5314 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5315 char *keyaltnames[] = {"mongoc_encryption_example_3"};
5316 bson_value_t datakey_id = {0};
5317 bson_value_t encrypted_field = {0};
5318 bson_value_t to_encrypt = {0};
5319 mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
5320 bson_value_t decrypted = {0};
5321
5322 mongoc_init ();
5323
5324 /* Configure the master key. This must be the same master key that was used
5325 * to create the encryption key. */
5326 local_masterkey =
5327 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5328 if (!local_masterkey || local_masterkey_len != 96) {
5329 fprintf (stderr,
5330 "Specify LOCAL_MASTERKEY environment variable as a "
5331 "secure random 96 byte hex value.\n");
5332 goto fail;
5333 }
5334
5335 kms_providers = BCON_NEW ("local",
5336 "{",
5337 "key",
5338 BCON_BIN (0, local_masterkey, local_masterkey_len),
5339 "}");
5340
5341 /* The mongoc_client_t used to read/write application data. */
5342 client =
5343 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5344 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5345
5346 /* Clear old data */
5347 mongoc_collection_drop (coll, NULL);
5348
5349 /* Set up the key vault for this example. */
5350 keyvault_coll =
5351 mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
5352 mongoc_collection_drop (keyvault_coll, NULL);
5353
5354 /* Create a unique index to ensure that two data keys cannot share the same
5355 * keyAltName. This is recommended practice for the key vault. */
5356 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5357 index_opts = BCON_NEW ("unique",
5358 BCON_BOOL (true),
5359 "partialFilterExpression",
5360 "{",
5361 "keyAltNames",
5362 "{",
5363 "$exists",
5364 BCON_BOOL (true),
5365 "}",
5366 "}");
5367 index_model = mongoc_index_model_new (index_keys, index_opts);
5368 ret = mongoc_collection_create_indexes_with_opts (keyvault_coll,
5369 &index_model,
5370 1,
5371 NULL /* opts */,
5372 NULL /* reply */,
5373 &error);
5374
5375 if (!ret) {
5376 goto fail;
5377 }
5378
5379 client_encryption_opts = mongoc_client_encryption_opts_new ();
5380 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5381 kms_providers);
5382 mongoc_client_encryption_opts_set_keyvault_namespace (
5383 client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5384
5385 /* Set a mongoc_client_t to use for reading/writing to the key vault. This
5386 * can be the same mongoc_client_t used by the main application. */
5387 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5388 client);
5389 client_encryption =
5390 mongoc_client_encryption_new (client_encryption_opts, &error);
5391 if (!client_encryption) {
5392 goto fail;
5393 }
5394
5395 /* Create a new data key for the encryptedField.
5396 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5397 */
5398 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5399 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5400 datakey_opts, keyaltnames, 1);
5401 if (!mongoc_client_encryption_create_datakey (
5402 client_encryption, "local", datakey_opts, &datakey_id, &error)) {
5403 goto fail;
5404 }
5405
5406 /* Explicitly encrypt a field */
5407 encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
5408 mongoc_client_encryption_encrypt_opts_set_algorithm (
5409 encrypt_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
5410 mongoc_client_encryption_encrypt_opts_set_keyid (encrypt_opts, &datakey_id);
5411 to_encrypt.value_type = BSON_TYPE_UTF8;
5412 to_encrypt.value.v_utf8.str = "123456789";
5413 const size_t len = strlen (to_encrypt.value.v_utf8.str);
5414 BSON_ASSERT (bson_in_range_unsigned (uint32_t, len));
5415 to_encrypt.value.v_utf8.len = (uint32_t) len;
5416
5417 ret = mongoc_client_encryption_encrypt (
5418 client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
5419 if (!ret) {
5420 goto fail;
5421 }
5422
5423 to_insert = bson_new ();
5424 BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
5425 ret = mongoc_collection_insert_one (
5426 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5427 if (!ret) {
5428 goto fail;
5429 }
5430
5431 printf ("encrypted document: ");
5432 if (!print_one_document (coll, &error)) {
5433 goto fail;
5434 }
5435 printf ("\n");
5436
5437 /* Explicitly decrypt a field */
5438 ret = mongoc_client_encryption_decrypt (
5439 client_encryption, &encrypted_field, &decrypted, &error);
5440 if (!ret) {
5441 goto fail;
5442 }
5443 printf ("decrypted value: %s\n", decrypted.value.v_utf8.str);
5444
5445 exit_status = EXIT_SUCCESS;
5446 fail:
5447 if (error.code) {
5448 fprintf (stderr, "error: %s\n", error.message);
5449 }
5450
5451 bson_free (local_masterkey);
5452 bson_destroy (kms_providers);
5453 mongoc_collection_destroy (keyvault_coll);
5454 mongoc_index_model_destroy (index_model);
5455 bson_destroy (index_opts);
5456 bson_destroy (index_keys);
5457 mongoc_collection_destroy (coll);
5458 mongoc_client_destroy (client);
5459 bson_destroy (to_insert);
5460 bson_destroy (schema);
5461 bson_destroy (create_cmd);
5462 bson_destroy (create_cmd_opts);
5463 mongoc_write_concern_destroy (wc);
5464 mongoc_client_encryption_destroy (client_encryption);
5465 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5466 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5467 bson_value_destroy (&encrypted_field);
5468 mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
5469 bson_value_destroy (&decrypted);
5470 bson_value_destroy (&datakey_id);
5471
5472 mongoc_cleanup ();
5473 return exit_status;
5474 }
5475
5476
5477 Explicit Encryption with Automatic Decryption
5478 Although automatic encryption requires MongoDB 4.2 enterprise or a Mon‐
5479 goDB 4.2 Atlas cluster, automatic decryption is supported for all
5480 users. To configure automatic decryption without automatic encryption
5481 set bypass_auto_encryption=True in mongoc_auto_encryption_opts_t:
5482
5483 client-side-encryption-auto-decryption.c
5484
5485 #include <mongoc/mongoc.h>
5486 #include <stdio.h>
5487 #include <stdlib.h>
5488
5489 #include "client-side-encryption-helpers.h"
5490
5491 /* This example demonstrates how to set up automatic decryption without
5492 * automatic encryption using the community version of MongoDB */
5493 int
5494 main (void)
5495 {
5496 /* The collection used to store the encryption data keys. */
5497 #define KEYVAULT_DB "encryption"
5498 #define KEYVAULT_COLL "__libmongocTestKeyVault"
5499 /* The collection used to store the encrypted documents in this example. */
5500 #define ENCRYPTED_DB "test"
5501 #define ENCRYPTED_COLL "coll"
5502
5503 int exit_status = EXIT_FAILURE;
5504 bool ret;
5505 uint8_t *local_masterkey = NULL;
5506 uint32_t local_masterkey_len;
5507 bson_t *kms_providers = NULL;
5508 bson_error_t error = {0};
5509 bson_t *index_keys = NULL;
5510 bson_t *index_opts = NULL;
5511 mongoc_index_model_t *index_model = NULL;
5512 bson_t *schema = NULL;
5513 mongoc_client_t *client = NULL;
5514 mongoc_collection_t *coll = NULL;
5515 mongoc_collection_t *keyvault_coll = NULL;
5516 bson_t *to_insert = NULL;
5517 bson_t *create_cmd = NULL;
5518 bson_t *create_cmd_opts = NULL;
5519 mongoc_write_concern_t *wc = NULL;
5520 mongoc_client_encryption_t *client_encryption = NULL;
5521 mongoc_client_encryption_opts_t *client_encryption_opts = NULL;
5522 mongoc_client_encryption_datakey_opts_t *datakey_opts = NULL;
5523 char *keyaltnames[] = {"mongoc_encryption_example_4"};
5524 bson_value_t datakey_id = {0};
5525 bson_value_t encrypted_field = {0};
5526 bson_value_t to_encrypt = {0};
5527 mongoc_client_encryption_encrypt_opts_t *encrypt_opts = NULL;
5528 bson_value_t decrypted = {0};
5529 mongoc_auto_encryption_opts_t *auto_encryption_opts = NULL;
5530 mongoc_client_t *unencrypted_client = NULL;
5531 mongoc_collection_t *unencrypted_coll = NULL;
5532
5533 mongoc_init ();
5534
5535 /* Configure the master key. This must be the same master key that was used
5536 * to create the encryption key. */
5537 local_masterkey =
5538 hex_to_bin (getenv ("LOCAL_MASTERKEY"), &local_masterkey_len);
5539 if (!local_masterkey || local_masterkey_len != 96) {
5540 fprintf (stderr,
5541 "Specify LOCAL_MASTERKEY environment variable as a "
5542 "secure random 96 byte hex value.\n");
5543 goto fail;
5544 }
5545
5546 kms_providers = BCON_NEW ("local",
5547 "{",
5548 "key",
5549 BCON_BIN (0, local_masterkey, local_masterkey_len),
5550 "}");
5551
5552 client =
5553 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5554 auto_encryption_opts = mongoc_auto_encryption_opts_new ();
5555 mongoc_auto_encryption_opts_set_keyvault_namespace (
5556 auto_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5557 mongoc_auto_encryption_opts_set_kms_providers (auto_encryption_opts,
5558 kms_providers);
5559
5560 /* Setting bypass_auto_encryption to true disables automatic encryption but
5561 * keeps the automatic decryption behavior. bypass_auto_encryption will also
5562 * disable spawning mongocryptd */
5563 mongoc_auto_encryption_opts_set_bypass_auto_encryption (auto_encryption_opts,
5564 true);
5565
5566 /* Once bypass_auto_encryption is set, community users can enable auto
5567 * encryption on the client. This will, in fact, only perform automatic
5568 * decryption. */
5569 ret = mongoc_client_enable_auto_encryption (
5570 client, auto_encryption_opts, &error);
5571 if (!ret) {
5572 goto fail;
5573 }
5574
5575 /* Now that automatic decryption is on, we can test it by inserting a
5576 * document with an explicitly encrypted value into the collection. When we
5577 * look up the document later, it should be automatically decrypted for us.
5578 */
5579 coll = mongoc_client_get_collection (client, ENCRYPTED_DB, ENCRYPTED_COLL);
5580
5581 /* Clear old data */
5582 mongoc_collection_drop (coll, NULL);
5583
5584 /* Set up the key vault for this example. */
5585 keyvault_coll =
5586 mongoc_client_get_collection (client, KEYVAULT_DB, KEYVAULT_COLL);
5587 mongoc_collection_drop (keyvault_coll, NULL);
5588
5589 /* Create a unique index to ensure that two data keys cannot share the same
5590 * keyAltName. This is recommended practice for the key vault. */
5591 index_keys = BCON_NEW ("keyAltNames", BCON_INT32 (1));
5592 index_opts = BCON_NEW ("unique",
5593 BCON_BOOL (true),
5594 "partialFilterExpression",
5595 "{",
5596 "keyAltNames",
5597 "{",
5598 "$exists",
5599 BCON_BOOL (true),
5600 "}",
5601 "}");
5602 index_model = mongoc_index_model_new (index_keys, index_opts);
5603 ret = mongoc_collection_create_indexes_with_opts (keyvault_coll,
5604 &index_model,
5605 1,
5606 NULL /* opts */,
5607 NULL /* reply */,
5608 &error);
5609
5610 if (!ret) {
5611 goto fail;
5612 }
5613
5614 client_encryption_opts = mongoc_client_encryption_opts_new ();
5615 mongoc_client_encryption_opts_set_kms_providers (client_encryption_opts,
5616 kms_providers);
5617 mongoc_client_encryption_opts_set_keyvault_namespace (
5618 client_encryption_opts, KEYVAULT_DB, KEYVAULT_COLL);
5619
5620 /* The key vault client is used for reading to/from the key vault. This can
5621 * be the same mongoc_client_t used by the application. */
5622 mongoc_client_encryption_opts_set_keyvault_client (client_encryption_opts,
5623 client);
5624 client_encryption =
5625 mongoc_client_encryption_new (client_encryption_opts, &error);
5626 if (!client_encryption) {
5627 goto fail;
5628 }
5629
5630 /* Create a new data key for the encryptedField.
5631 * https://dochub.mongodb.org/core/client-side-field-level-encryption-automatic-encryption-rules
5632 */
5633 datakey_opts = mongoc_client_encryption_datakey_opts_new ();
5634 mongoc_client_encryption_datakey_opts_set_keyaltnames (
5635 datakey_opts, keyaltnames, 1);
5636 ret = mongoc_client_encryption_create_datakey (
5637 client_encryption, "local", datakey_opts, &datakey_id, &error);
5638 if (!ret) {
5639 goto fail;
5640 }
5641
5642 /* Explicitly encrypt a field. */
5643 encrypt_opts = mongoc_client_encryption_encrypt_opts_new ();
5644 mongoc_client_encryption_encrypt_opts_set_algorithm (
5645 encrypt_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
5646 mongoc_client_encryption_encrypt_opts_set_keyaltname (
5647 encrypt_opts, "mongoc_encryption_example_4");
5648 to_encrypt.value_type = BSON_TYPE_UTF8;
5649 to_encrypt.value.v_utf8.str = "123456789";
5650 const size_t len = strlen (to_encrypt.value.v_utf8.str);
5651 BSON_ASSERT (bson_in_range_unsigned (uint32_t, len));
5652 to_encrypt.value.v_utf8.len = (uint32_t) len;
5653
5654 ret = mongoc_client_encryption_encrypt (
5655 client_encryption, &to_encrypt, encrypt_opts, &encrypted_field, &error);
5656 if (!ret) {
5657 goto fail;
5658 }
5659
5660 to_insert = bson_new ();
5661 BSON_APPEND_VALUE (to_insert, "encryptedField", &encrypted_field);
5662 ret = mongoc_collection_insert_one (
5663 coll, to_insert, NULL /* opts */, NULL /* reply */, &error);
5664 if (!ret) {
5665 goto fail;
5666 }
5667
5668 /* When we retrieve the document, any encrypted fields will get automatically
5669 * decrypted by the driver. */
5670 printf ("decrypted document: ");
5671 if (!print_one_document (coll, &error)) {
5672 goto fail;
5673 }
5674 printf ("\n");
5675
5676 unencrypted_client =
5677 mongoc_client_new ("mongodb://localhost/?appname=client-side-encryption");
5678 unencrypted_coll = mongoc_client_get_collection (
5679 unencrypted_client, ENCRYPTED_DB, ENCRYPTED_COLL);
5680
5681 printf ("encrypted document: ");
5682 if (!print_one_document (unencrypted_coll, &error)) {
5683 goto fail;
5684 }
5685 printf ("\n");
5686
5687 exit_status = EXIT_SUCCESS;
5688 fail:
5689 if (error.code) {
5690 fprintf (stderr, "error: %s\n", error.message);
5691 }
5692
5693 bson_free (local_masterkey);
5694 bson_destroy (kms_providers);
5695 mongoc_collection_destroy (keyvault_coll);
5696 mongoc_index_model_destroy (index_model);
5697 bson_destroy (index_opts);
5698 bson_destroy (index_keys);
5699 mongoc_collection_destroy (coll);
5700 mongoc_client_destroy (client);
5701 bson_destroy (to_insert);
5702 bson_destroy (schema);
5703 bson_destroy (create_cmd);
5704 bson_destroy (create_cmd_opts);
5705 mongoc_write_concern_destroy (wc);
5706 mongoc_client_encryption_destroy (client_encryption);
5707 mongoc_client_encryption_datakey_opts_destroy (datakey_opts);
5708 mongoc_client_encryption_opts_destroy (client_encryption_opts);
5709 bson_value_destroy (&encrypted_field);
5710 mongoc_client_encryption_encrypt_opts_destroy (encrypt_opts);
5711 bson_value_destroy (&decrypted);
5712 bson_value_destroy (&datakey_id);
5713 mongoc_collection_destroy (unencrypted_coll);
5714 mongoc_client_destroy (unencrypted_client);
5715 mongoc_auto_encryption_opts_destroy (auto_encryption_opts);
5716
5717 mongoc_cleanup ();
5718 return exit_status;
5719 }
5720
5721
5722 Queryable Encryption
5723 Using Queryable Encryption requires MongoDB Server 7.0 or higher.
5724
5725 See the MongoDB Manual for Queryable Encryption for more information
5726 about the feature.
5727
5728 API related to the "rangePreview" algorithm is still experimental and
5729 subject to breaking changes!
5730
5731 Queryable Encryption in older MongoDB Server versions
5732 MongoDB Server 6.0 introduced Queryable Encryption as a Public Techni‐
5733 cal Preview. MongoDB Server 7.0 includes backwards breaking changes to
5734 the Queryable Encryption protocol.
5735
5736 The backwards breaking changes are applied in the client protocol in
5737 libmongocrypt 1.8.0. libmongoc 1.24.0 requires libmongocrypt 1.8.0 or
5738 newer. libmongoc 1.24.0 no longer supports Queryable Encryption in
5739 MongoDB Server <7.0. Using Queryable Encryption libmongoc 1.24.0 and
5740 higher requires MongoDB Server >=7.0.
5741
5742 Using Queryable Encryption with libmongocrypt<1.8.0 on a MongoDB
5743 Server>=7.0, or using libmongocrypt>=1.8.0 on a MongoDB Server<6.0 will
5744 result in a server error when using the incompatible protocol.
5745
5746 SEE ALSO:
5747 The MongoDB Manual for Queryable Encryption
5748
5749
5750 Installation
5751 Using In-Use Encryption in the C driver requires the dependency libmon‐
5752 gocrypt. See the MongoDB Manual for libmongocrypt installation instruc‐
5753 tions.
5754
5755 Once libmongocrypt is installed, configure the C driver with -DEN‐
5756 ABLE_CLIENT_SIDE_ENCRYPTION=ON to require In-Use Encryption be enabled.
5757
5758 $ cd mongo-c-driver
5759 $ mkdir cmake-build && cd cmake-build
5760 $ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF -DENABLE_CLIENT_SIDE_ENCRYPTION=ON ..
5761 $ cmake --build . --target install
5762
5763 API
5764 mongoc_client_encryption_t is used for explicit encryption and key man‐
5765 agement. mongoc_client_enable_auto_encryption() and
5766 mongoc_client_pool_enable_auto_encryption() is used to enable automatic
5767 encryption.
5768
5769 The Queryable Encryption and CSFLE features share much of the same API
5770 with some exceptions.
5771
5772 • The supported algorithms documented in
5773 mongoc_client_encryption_encrypt_opts_set_algorithm() do not apply to
5774 both features.
5775
5776 • mongoc_auto_encryption_opts_set_encrypted_fields_map() only applies
5777 to Queryable Encryption.
5778
5779 • mongoc_auto_encryption_opts_set_schema_map() only applies to CSFLE.
5780
5781 Query Analysis
5782 To support the automatic encryption feature, one of the following de‐
5783 pendencies are required:
5784
5785 • The mongocryptd executable. See the MongoDB Manual documentation:
5786 Install and Configure mongocryptd
5787
5788 • The crypt_shared library. See the MongoDB Manual documentation:
5789 Automatic Encryption Shared Library
5790
5791 A mongoc_client_t or mongoc_client_pool_t configured with auto encryp‐
5792 tion will automatically try to load the crypt_shared library. If load‐
5793 ing the crypt_shared library fails, the mongoc_client_t or
5794 mongoc_client_pool_t will try to spawn the mongocryptd process from the
5795 application's PATH. To configure use of crypt_shared and mongocryptd
5796 see mongoc_auto_encryption_opts_set_extra().
5797
5798 API Reference
5799 Initialization and cleanup
5800 Synopsis
5801 Initialize the MongoDB C Driver by calling mongoc_init() exactly once
5802 at the beginning of your program. It is responsible for initializing
5803 global state such as process counters, SSL, and threading primitives.
5804
5805 Exception to this is mongoc_log_set_handler(), which should be called
5806 before mongoc_init() or some log traces would not use your log handling
5807 function. See Custom Log Handlers for a detailed example.
5808
5809 Call mongoc_cleanup() exactly once at the end of your program to re‐
5810 lease all memory and other resources allocated by the driver. You must
5811 not call any other MongoDB C Driver functions after mongoc_cleanup().
5812 Note that mongoc_init() does not reinitialize the driver after
5813 mongoc_cleanup().
5814
5815 Deprecated feature: automatic initialization and cleanup
5816 On some platforms the driver can automatically call mongoc_init() be‐
5817 fore main, and call mongoc_cleanup() as the process exits. This is
5818 problematic in situations where related libraries also execute cleanup
5819 code on shutdown, and it creates inconsistent rules across platforms.
5820 Therefore the automatic initialization and cleanup feature is depre‐
5821 cated, and will be dropped in version 2.0. Meanwhile, for backward com‐
5822 patibility, the feature is enabled by default on platforms where it is
5823 available.
5824
5825 For portable, future-proof code, always call mongoc_init() and
5826 mongoc_cleanup() yourself, and configure the driver like:
5827
5828 cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF
5829
5830 Logging
5831 MongoDB C driver Logging Abstraction
5832
5833 Synopsis
5834 typedef enum {
5835 MONGOC_LOG_LEVEL_ERROR,
5836 MONGOC_LOG_LEVEL_CRITICAL,
5837 MONGOC_LOG_LEVEL_WARNING,
5838 MONGOC_LOG_LEVEL_MESSAGE,
5839 MONGOC_LOG_LEVEL_INFO,
5840 MONGOC_LOG_LEVEL_DEBUG,
5841 MONGOC_LOG_LEVEL_TRACE,
5842 } mongoc_log_level_t;
5843
5844 #define MONGOC_ERROR(...)
5845 #define MONGOC_CRITICAL(...)
5846 #define MONGOC_WARNING(...)
5847 #define MONGOC_MESSAGE(...)
5848 #define MONGOC_INFO(...)
5849 #define MONGOC_DEBUG(...)
5850
5851 typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level,
5852 const char *log_domain,
5853 const char *message,
5854 void *user_data);
5855
5856 void
5857 mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data);
5858 void
5859 mongoc_log (mongoc_log_level_t log_level,
5860 const char *log_domain,
5861 const char *format,
5862 ...) BSON_GNUC_PRINTF (3, 4);
5863 const char *
5864 mongoc_log_level_str (mongoc_log_level_t log_level);
5865 void
5866 mongoc_log_default_handler (mongoc_log_level_t log_level,
5867 const char *log_domain,
5868 const char *message,
5869 void *user_data);
5870 void
5871 mongoc_log_trace_enable (void);
5872 void
5873 mongoc_log_trace_disable (void);
5874
5875 The MongoDB C driver comes with an abstraction for logging that you can
5876 use in your application, or integrate with an existing logging system.
5877
5878 Macros
5879 To make logging a little less painful, various helper macros are pro‐
5880 vided. See the following example.
5881
5882 #undef MONGOC_LOG_DOMAIN
5883 #define MONGOC_LOG_DOMAIN "my-custom-domain"
5884
5885 MONGOC_WARNING ("An error occurred: %s", strerror (errno));
5886
5887 Custom Log Handlers
5888 The default log handler prints a timestamp and the log message to std‐
5889 out, or to stderr for warnings, critical messages, and errors.
5890 You can override the handler with mongoc_log_set_handler().
5891 Your handler function is called in a mutex for thread safety.
5892
5893 For example, you could register a custom handler to suppress messages
5894 at INFO level and below:
5895
5896 void
5897 my_logger (mongoc_log_level_t log_level,
5898 const char *log_domain,
5899 const char *message,
5900 void *user_data)
5901 {
5902 /* smaller values are more important */
5903 if (log_level < MONGOC_LOG_LEVEL_INFO) {
5904 mongoc_log_default_handler (log_level, log_domain, message, user_data);
5905 }
5906 }
5907
5908 int
5909 main (int argc, char *argv[])
5910 {
5911 mongoc_log_set_handler (my_logger, NULL);
5912 mongoc_init ();
5913
5914 /* ... your code ... */
5915
5916 mongoc_cleanup ();
5917 return 0;
5918 }
5919
5920 Note that in the example above mongoc_log_set_handler() is called be‐
5921 fore mongoc_init(). Otherwise, some log traces could not be processed
5922 by the log handler.
5923
5924 To restore the default handler:
5925
5926 mongoc_log_set_handler (mongoc_log_default_handler, NULL);
5927
5928 Disable logging
5929 To disable all logging, including warnings, critical messages and er‐
5930 rors, provide an empty log handler:
5931
5932 mongoc_log_set_handler (NULL, NULL);
5933
5934 Tracing
5935 If compiling your own copy of the MongoDB C driver, consider configur‐
5936 ing with -DENABLE_TRACING=ON to enable function tracing and hex dumps
5937 of network packets to STDERR and STDOUT during development and debug‐
5938 ging.
5939
5940 This is especially useful when debugging what may be going on inter‐
5941 nally in the driver.
5942
5943 Trace messages can be enabled and disabled by calling mon‐
5944 goc_log_trace_enable() and mongoc_log_trace_disable()
5945
5946 NOTE:
5947 Compiling the driver with -DENABLE_TRACING=ON will affect its per‐
5948 formance. Disabling tracing with mongoc_log_trace_disable() signifi‐
5949 cantly reduces the overhead, but cannot remove it completely.
5950 « libmongoc
5951
5952 Error Reporting
5953 Description
5954 Many C Driver functions report errors by returning false or -1 and
5955 filling out a bson_error_t structure with an error domain, error code,
5956 and message. Use domain to determine which subsystem generated the er‐
5957 ror, and code for the specific error. message is a human-readable error
5958 description.
5959
5960 SEE ALSO:
5961 Handling Errors in libbson.
5962
5963
5964┌────────────────────┬──────────────────────────────────┬────────────────────────────────────────────┐
5965│Code │ Description │ │
5966├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5967│MONGOC_ERROR_CLIENT │ MONGOC_ER‐ │ You tried to send a │
5968│ │ ROR_CLIENT_TOO_BIG │ message larger than │
5969│ │ │ the server's max │
5970│ │ │ message size. │
5971├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5972│ │ MONGOC_ER‐ │ Wrong credentials, │
5973│ │ ROR_CLIENT_AUTHEN‐ │ or failure sending │
5974│ │ TICATE │ or receiving au‐ │
5975│ │ │ thentication mes‐ │
5976│ │ │ sages. │
5977├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5978│ │ MONGOC_ER‐ │ You tried an TLS │
5979│ │ ROR_CLIENT_NO_AC‐ │ connection but the │
5980│ │ CEPTABLE_PEER │ driver was not │
5981│ │ │ built with TLS. │
5982├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5983│ │ MONGOC_ER‐ │ You began iterating │
5984│ │ ROR_CLIENT_IN_EX‐ │ an exhaust cursor, │
5985│ │ HAUST │ then tried to begin │
5986│ │ │ another operation │
5987│ │ │ with the same │
5988│ │ │ mongoc_client_t. │
5989├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5990│ │ MONGOC_ER‐ │ Failure related to │
5991│ │ ROR_CLIENT_SES‐ │ creating or using a │
5992│ │ SION_FAILURE │ logical session. │
5993├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5994│ │ MONGOC_ER‐ │ Failure related to │
5995│ │ ROR_CLIENT_IN‐ │ arguments passed │
5996│ │ VALID_ENCRYP‐ │ when initializing │
5997│ │ TION_ARG │ In-Use Encryption. │
5998├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
5999│ │ MONGOC_ER‐ │ Failure related to │
6000│ │ ROR_CLIENT_IN‐ │ In-Use Encryption. │
6001│ │ VALID_ENCRYP‐ │ │
6002│ │ TION_STATE │ │
6003└────────────────────┴──────────────────────────────────┴────────────────────────────────────────────┘
6004
6005
6006
6007
6008
6009
6010
6011│ │ MONGOC_ER‐ │ You attempted to │
6012│ │ ROR_CLIENT_IN‐ │ connect to a Mon‐ │
6013│ │ VALID_LOAD_BALANCER │ goDB server behind │
6014│ │ │ a load balancer, │
6015│ │ │ but the server does │
6016│ │ │ not advertize load │
6017│ │ │ balanced support. │
6018├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6019│MONGOC_ERROR_STREAM │ MONGOC_ER‐ │ DNS failure. │
6020│ │ ROR_STREAM_NAME_RES‐ │ │
6021│ │ OLUTION │ │
6022├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6023│ │ MONGOC_ER‐ │ Timeout communicat‐ │
6024│ │ ROR_STREAM_SOCKET │ ing with server, or │
6025│ │ │ connection closed. │
6026├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6027│ │ MONGOC_ER‐ │ Failed to connect │
6028│ │ ROR_STREAM_CONNECT │ to server. │
6029├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6030│MONGOC_ERROR_PROTO‐ │ MONGOC_ERROR_PROTO‐ │ Corrupt response │
6031│COL │ COL_INVALID_REPLY │ from server. │
6032├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6033│ │ MONGOC_ERROR_PROTO‐ │ The server version │
6034│ │ COL_BAD_WIRE_VERSION │ is too old or too │
6035│ │ │ new to communicate │
6036│ │ │ with the driver. │
6037├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6038│MONGOC_ERROR_CURSOR │ MONGOC_ERROR_CUR‐ │ You passed bad ar‐ │
6039│ │ SOR_INVALID_CURSOR │ guments to │
6040│ │ │ mongoc_collection_find_with_opts(), │
6041│ │ │ or you called │
6042│ │ │ mongoc_cursor_next() │
6043│ │ │ on a completed or │
6044│ │ │ failed cursor, or │
6045│ │ │ the cursor timed │
6046│ │ │ out on the server. │
6047├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6048│ │ MONGOC_ER‐ │ A resume token was not returned in │
6049│ │ ROR_CHANGE_STREAM_NO_RE‐ │ a document found with │
6050│ │ SUME_TOKEN │ mongoc_change_stream_next() │
6051├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6052│MONGOC_ERROR_QUERY │ MONGOC_ERROR_QUERY_FAIL‐ │ Error API Version 1: Server error │
6053│ │ URE │ from command or query. The server │
6054│ │ │ error message is in message. │
6055├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6056│MONGOC_ERROR_SERVER │ MONGOC_ERROR_QUERY_FAIL‐ │ Error API Version 2: Server error │
6057│ │ URE │ from command or query. The server │
6058│ │ │ error message is in message. │
6059├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6060│MONGOC_ERROR_SASL │ A SASL error code. │ man sasl_errors for a list of │
6061│ │ │ codes. │
6062├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6063│MONGOC_ERROR_BSON │ MONGOC_ERROR_BSON_IN‐ │ You passed an invalid or oversized │
6064│ │ VALID │ BSON document as a parameter, or │
6065│ │ │ called │
6066│ │ │ mongoc_collection_create_index() │
6067│ │ │ with invalid keys, or the server │
6068│ │ │ reply was corrupt. │
6069├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6070│MONGOC_ERROR_NAME‐ │ MONGOC_ERROR_NAME‐ │ You tried to create a collection │
6071│SPACE │ SPACE_INVALID │ with an invalid name. │
6072├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6073│MONGOC_ERROR_COM‐ │ MONGOC_ERROR_COMMAND_IN‐ │ Many functions set this error code │
6074│MAND │ VALID_ARG │ when passed bad parameters. Print │
6075│ │ │ the error message for details. │
6076└────────────────────┴──────────────────────────────────┴────────────────────────────────────────────┘
6077
6078│ │ MONGOC_ERROR_PROTO‐ │ You tried to use a command option │
6079│ │ COL_BAD_WIRE_VERSION │ the server does not support. │
6080├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6081│ │ MONGOC_ERROR_DUPLI‐ │ An insert or update failed because │
6082│ │ CATE_KEY │ because of a duplicate _id or other │
6083│ │ │ unique-index violation. │
6084├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6085│ │ MONGOC_ER‐ │ The operation failed because max‐ │
6086│ │ ROR_MAX_TIME_MS_EXPIRED │ TimeMS expired. │
6087├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6088│ │ MONGOC_ERROR_SERVER_SE‐ │ The serverId option for an opera‐ │
6089│ │ LECTION_INVALID_ID │ tion conflicts with the pinned │
6090│ │ │ server for that operation's client │
6091│ │ │ session (denoted by the sessionId │
6092│ │ │ option). │
6093├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6094│MONGOC_ERROR_COM‐ │ Error code from server. │ Error API Version 1: Server error │
6095│MAND │ │ from a command. The server error │
6096│ │ │ message is in message. │
6097├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6098│MONGOC_ERROR_SERVER │ Error code from server. │ Error API Version 2: Server error │
6099│ │ │ from a command. The server error │
6100│ │ │ message is in message. │
6101├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6102│MONGOC_ERROR_COL‐ │ MONGOC_ERROR_COLLEC‐ │ Invalid or empty input to │
6103│LECTION │ TION_INSERT_FAILED, MON‐ │ mongoc_collection_insert_one(), │
6104│ │ GOC_ERROR_COLLECTION_UP‐ │ mongoc_collection_insert_bulk(), │
6105│ │ DATE_FAILED, MONGOC_ER‐ │ mongoc_collection_update_one(), │
6106│ │ ROR_COLLEC‐ │ mongoc_collection_update_many(), │
6107│ │ TION_DELETE_FAILED. │ mongoc_collection_replace_one(), │
6108│ │ │ mongoc_collection_delete_one(), or │
6109│ │ │ mongoc_collection_delete_many(). │
6110├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6111│MONGOC_ERROR_COL‐ │ Error code from server. │ Error API Version 1: Server error │
6112│LECTION │ │ from │
6113│ │ │ mongoc_collection_insert_one(), │
6114│ │ │ mongoc_collection_insert_bulk(), │
6115│ │ │ mongoc_collection_update_one(), │
6116│ │ │ mongoc_collection_update_many(), │
6117│ │ │ mongoc_collection_replace_one(), │
6118├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6119│MONGOC_ERROR_SERVER │ Error code from server. │ Error API Version 2: Server error │
6120│ │ │ from │
6121│ │ │ mongoc_collection_insert_one(), │
6122│ │ │ mongoc_collection_insert_bulk(), │
6123│ │ │ mongoc_collection_update_one(), │
6124│ │ │ mongoc_collection_update_many(), │
6125│ │ │ mongoc_collection_replace_one(), │
6126├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6127│MONGOC_ERROR_GRIDFS │ MONGOC_ER‐ │ The GridFS file is missing a docu‐ │
6128│ │ ROR_GRIDFS_CHUNK_MISSING │ ment in its chunks collection. │
6129├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6130│ │ MONGOC_ERROR_GRIDFS_COR‐ │ A data inconsistency was detected │
6131│ │ RUPT │ in GridFS. │
6132├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6133│ │ MONGOC_ERROR_GRIDFS_IN‐ │ You passed a NULL filename to │
6134│ │ VALID_FILENAME │ mongoc_gridfs_remove_by_filename(). │
6135├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6136│ │ MONGOC_ERROR_GRIDFS_PRO‐ │ You called │
6137│ │ TOCOL_ERROR │ mongoc_gridfs_file_set_id() after │
6138│ │ │ mongoc_gridfs_file_save(), or tried │
6139│ │ │ to write on a closed GridFS stream. │
6140├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6141│ │ MONGOC_ER‐ │ A GridFS file is missing from files │
6142│ │ ROR_GRIDFS_BUCKET_FILE_NOT_FOUND │ collection. │
6143└────────────────────┴──────────────────────────────────┴────────────────────────────────────────────┘
6144
6145│ │ MONGOC_ER‐ │ An error occurred on a stream cre‐ │
6146│ │ ROR_GRIDFS_BUCKET_STREAM │ ated from a GridFS operation like │
6147│ │ │ mongoc_gridfs_bucket_upload_from_stream(). │
6148├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6149│MONGOC_ERROR_SCRAM │ MONGOC_ERROR_SCRAM_PROTOCOL_ER‐ │ Failure in SCRAM-SHA-1 authentication. │
6150│ │ ROR │ │
6151├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6152│MONGOC_ER‐ │ MONGOC_ERROR_SERVER_SELEC‐ │ No replica set member or mongos is avail‐ │
6153│ROR_SERVER_SELEC‐ │ TION_FAILURE │ able, or none matches your read prefer‐ │
6154│TION │ │ ence, or you supplied an invalid │
6155│ │ │ mongoc_read_prefs_t. │
6156├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6157│MONGOC_ER‐ │ Error code from server. │ There was a write concern error or timeout │
6158│ROR_WRITE_CONCERN │ │ from the server. │
6159├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6160│MONGOC_ERROR_TRANS‐ │ MONGOC_ERROR_TRANSACTION_INVALID │ You attempted to start a transaction when │
6161│ACTION │ │ one is already in progress, or commit or │
6162│ │ │ abort when there is no transaction. │
6163├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6164│MONGOC_ER‐ │ Error code produced by libmon‐ │ An error occurred in the library responsi‐ │
6165│ROR_CLIENT_SIDE_EN‐ │ gocrypt. │ ble for In-Use Encryption │
6166│CRYPTION │ │ │
6167├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6168│MONGOC_ERROR_AZURE │ MONGOC_ERROR_KMS_SERVER_HTTP │ An Azure HTTP service responded with an │
6169│ │ │ error status │
6170├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6171│ │ MONGOC_ERROR_KMS_SERVER_BAD_JSON │ An Azure service responded with invalid │
6172│ │ │ JSON data │
6173├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6174│MONGOC_ERROR_GCP │ MONGOC_ERROR_KMS_SERVER_HTTP │ A GCP HTTP service responded with an error │
6175│ │ │ status │
6176├────────────────────┼──────────────────────────────────┼────────────────────────────────────────────┤
6177│ │ MONGOC_ERROR_KMS_SERVER_BAD_JSON │ A GCP service responded with invalid JSON │
6178│ │ │ data │
6179└────────────────────┴──────────────────────────────────┴────────────────────────────────────────────┘
6180
6181 Error Labels
6182 In some cases your application must make decisions based on what cate‐
6183 gory of error the driver has returned, but these categories do not cor‐
6184 respond perfectly to an error domain or code. In such cases, error la‐
6185 bels provide a reliable way to determine how your application should
6186 respond to an error.
6187
6188 Any C Driver function that has a bson_t out-parameter named reply may
6189 include error labels to the reply, in the form of a BSON field named
6190 "errorLabels" containing an array of strings:
6191
6192 { "errorLabels": [ "TransientTransactionError" ] }
6193
6194 Use mongoc_error_has_label() to test if a reply contains a specific la‐
6195 bel. See mongoc_client_session_start_transaction() for example code
6196 that demonstrates the use of error labels in application logic.
6197
6198 The following error labels are currently defined. Future versions of
6199 MongoDB may introduce new labels.
6200
6201 TransientTransactionError
6202 Within a multi-document transaction, certain errors can leave the
6203 transaction in an unknown or aborted state. These include write con‐
6204 flicts, primary stepdowns, and network errors. In response, the appli‐
6205 cation should abort the transaction and try the same sequence of opera‐
6206 tions again in a new transaction.
6207
6208 UnknownTransactionCommitResult
6209 When mongoc_client_session_commit_transaction() encounters a network
6210 error or certain server errors, it is not known whether the transaction
6211 was committed. Applications should attempt to commit the transaction
6212 again until: the commit succeeds, the commit fails with an error not
6213 labeled "UnknownTransactionCommitResult", or the application chooses to
6214 give up.
6215
6216 Setting the Error API Version
6217 The driver's error reporting began with a design flaw: when the error
6218 domain is MONGOC_ERROR_COLLECTION, MONGOC_ERROR_QUERY, or MONGOC_ER‐
6219 ROR_COMMAND, the error code might originate from the server or the
6220 driver. An application cannot always know where an error originated,
6221 and therefore cannot tell what the code means.
6222
6223 For example, if mongoc_collection_update_one() sets the error's domain
6224 to MONGOC_ERROR_COLLECTION and its code to 24, the application cannot
6225 know whether 24 is the generic driver error code MONGOC_ERROR_COLLEC‐
6226 TION_UPDATE_FAILED or the specific server error code "LockTimeout".
6227
6228 To fix this flaw while preserving backward compatibility, the C Driver
6229 1.4 introduces "Error API Versions". Version 1, the default Error API
6230 Version, maintains the flawed behavior. Version 2 adds a new error do‐
6231 main, MONGOC_ERROR_SERVER. In Version 2, error codes originating on the
6232 server always have error domain MONGOC_ERROR_SERVER or MONGOC_ER‐
6233 ROR_WRITE_CONCERN. When the driver uses Version 2 the application can
6234 always determine the origin and meaning of error codes. New applica‐
6235 tions should use Version 2, and existing applications should be updated
6236 to use Version 2 as well.
6237
6238┌──────────────────────────────────────────────┬────────────────────┬─────────────────────┐
6239│Error Source │ API Version 1 │ API Version 2 │
6240├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6241│mongoc_cursor_error() │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6242├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6243│mongoc_client_command_with_opts(), │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6244│mongoc_database_command_with_opts(), │ │ │
6245│and other command │ │ │
6246│functions │ │ │
6247├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6248│mongoc_collection_count_with_opts() │ MONGOC_ERROR_QUERY │ MONGOC_ERROR_SERVER │
6249│mongoc_client_get_database_names_with_opts(), │ │ │
6250│and other command helper functions │ │ │
6251├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6252│mongoc_collection_insert_one() │ MONGOC_ERROR_COM‐ │ MONGOC_ERROR_SERVER │
6253│mongoc_collection_insert_bulk() │ MAND │ │
6254│mongoc_collection_update_one() │ │ │
6255│mongoc_collection_update_many() │ │ │
6256│mongoc_collection_replace_one() │ │ │
6257│mongoc_collection_delete_one() │ │ │
6258│mongoc_collection_delete_many() │ │ │
6259├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6260│mongoc_bulk_operation_execute() │ MONGOC_ERROR_COM‐ │ MONGOC_ERROR_SERVER │
6261│ │ MAND │ │
6262├──────────────────────────────────────────────┼────────────────────┼─────────────────────┤
6263│Write-concern timeout │ MONGOC_ER‐ │ MONGOC_ER‐ │
6264│ │ ROR_WRITE_CONCERN │ ROR_WRITE_CONCERN │
6265└──────────────────────────────────────────────┴────────────────────┴─────────────────────┘
6266
6267 The Error API Versions are defined with MONGOC_ERROR_API_VERSION_LEGACY
6268 and MONGOC_ERROR_API_VERSION_2. Set the version with
6269 mongoc_client_set_error_api() or mongoc_client_pool_set_error_api().
6270
6271 SEE ALSO:
6272 MongoDB Server Error Codes
6273
6274
6275 Object Lifecycle
6276 This page documents the order of creation and destruction for libmon‐
6277 goc's main struct types.
6278
6279 Clients and pools
6280 Call mongoc_init() once, before calling any other libmongoc functions,
6281 and call mongoc_cleanup() once before your program exits.
6282
6283 A program that uses libmongoc from multiple threads should create a
6284 mongoc_client_pool_t with mongoc_client_pool_new(). Each thread ac‐
6285 quires a mongoc_client_t from the pool with mongoc_client_pool_pop()
6286 and returns it with mongoc_client_pool_push() when the thread is fin‐
6287 ished using it. To destroy the pool, first return all clients, then
6288 call mongoc_client_pool_destroy().
6289
6290 If your program uses libmongoc from only one thread, create a
6291 mongoc_client_t directly with mongoc_client_new() or
6292 mongoc_client_new_from_uri(). Destroy it with mongoc_client_destroy().
6293
6294 Databases, collections, and related objects
6295 You can create a mongoc_database_t or mongoc_collection_t from a
6296 mongoc_client_t, and create a mongoc_cursor_t or
6297 mongoc_bulk_operation_t from a mongoc_collection_t.
6298
6299 Each of these objects must be destroyed before the client they were
6300 created from, but their lifetimes are otherwise independent.
6301
6302 GridFS objects
6303 You can create a mongoc_gridfs_t from a mongoc_client_t, create a
6304 mongoc_gridfs_file_t or mongoc_gridfs_file_list_t from a
6305 mongoc_gridfs_t, create a mongoc_gridfs_file_t from a
6306 mongoc_gridfs_file_list_t, and create a mongoc_stream_t from a
6307 mongoc_gridfs_file_t.
6308
6309 Each of these objects depends on the object it was created from. Always
6310 destroy GridFS objects in the reverse of the order they were created.
6311 The sole exception is that a mongoc_gridfs_file_t need not be destroyed
6312 before the mongoc_gridfs_file_list_t it was created from.
6313
6314 GridFS bucket objects
6315 Create mongoc_gridfs_bucket_t with a mongoc_database_t derived from a
6316 mongoc_client_t. The mongoc_database_t is independent from the
6317 mongoc_gridfs_bucket_t. But the mongoc_client_t must outlive the
6318 mongoc_gridfs_bucket_t.
6319
6320 A mongoc_stream_t may be created from the mongoc_gridfs_bucket_t. The
6321 mongoc_gridfs_bucket_t must outlive the mongoc_stream_t.
6322
6323 Sessions
6324 Start a session with mongoc_client_start_session(), use the session for
6325 a sequence of operations and multi-document transactions, then free it
6326 with mongoc_client_session_destroy(). Any mongoc_cursor_t or
6327 mongoc_change_stream_t using a session must be destroyed before the
6328 session, and a session must be destroyed before the mongoc_client_t it
6329 came from.
6330
6331 By default, sessions are causally consistent. To disable causal consis‐
6332 tency, before starting a session create a mongoc_session_opt_t with
6333 mongoc_session_opts_new() and call
6334 mongoc_session_opts_set_causal_consistency(), then free the struct with
6335 mongoc_session_opts_destroy().
6336
6337 Unacknowledged writes are prohibited with sessions.
6338
6339 A mongoc_client_session_t must be used by only one thread at a time.
6340 Due to session pooling, mongoc_client_start_session() may return a ses‐
6341 sion that has been idle for some time and is about to be closed after
6342 its idle timeout. Use the session within one minute of acquiring it to
6343 refresh the session and avoid a timeout.
6344
6345 Client Side Encryption
6346 When configuring a mongoc_client_t for automatic encryption via
6347 mongoc_client_enable_auto_encryption(), if a separate key vault client
6348 is set in the options (via
6349 mongoc_auto_encryption_opts_set_keyvault_client()) the key vault client
6350 must outlive the encrypted client.
6351
6352 When configuring a mongoc_client_pool_t for automatic encryption via
6353 mongoc_client_pool_enable_auto_encryption(), if a separate key vault
6354 client pool is set in the options (via
6355 mongoc_auto_encryption_opts_set_keyvault_client_pool()) the key vault
6356 client pool must outlive the encrypted client pool.
6357
6358 When creating a mongoc_client_encryption_t, the configured key vault
6359 client (set via mongoc_client_encryption_opts_set_keyvault_client())
6360 must outlive the mongoc_client_encryption_t.
6361
6362 GridFS
6363 The C driver includes two APIs for GridFS.
6364
6365 The older API consists of mongoc_gridfs_t and its derivatives. It con‐
6366 tains deprecated API, does not support read preferences, and is not
6367 recommended in new applications. It does not conform to the MongoDB
6368 GridFS specification.
6369
6370 The newer API consists of mongoc_gridfs_bucket_t and allows upload‐
6371 ing/downloading through derived mongoc_stream_t objects. It conforms to
6372 the MongoDB GridFS specification.
6373
6374 There is not always a straightforward upgrade path from an application
6375 built with mongoc_gridfs_t to mongoc_gridfs_bucket_t (e.g. a
6376 mongoc_gridfs_file_t provides functions to seek but mongoc_stream_t
6377 does not). But users are encouraged to upgrade when possible.
6378
6379 mongoc_auto_encryption_opts_t
6380 Options for enabling automatic encryption and decryption for In-Use En‐
6381 cryption.
6382
6383 Synopsis
6384 typedef struct _mongoc_auto_encryption_opts_t mongoc_auto_encryption_opts_t;
6385
6386 SEE ALSO:
6387 In-Use Encryption
6388
6389
6390 mongoc_bulk_operation_t
6391 Bulk Write Operations
6392
6393 Synopsis
6394 typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t;
6395
6396 The opaque type mongoc_bulk_operation_t provides an abstraction for
6397 submitting multiple write operations as a single batch.
6398
6399 After adding all of the write operations to the mongoc_bulk_opera‐
6400 tion_t, call mongoc_bulk_operation_execute() to execute the operation.
6401
6402 WARNING:
6403 It is only valid to call mongoc_bulk_operation_execute() once. The
6404 mongoc_bulk_operation_t must be destroyed afterwards.
6405
6406 SEE ALSO:
6407 Bulk Write Operations
6408
6409
6410 mongoc_change_stream_t
6411 Synopsis
6412 #include <mongoc/mongoc.h>
6413
6414 typedef struct _mongoc_change_stream_t mongoc_change_stream_t;
6415
6416 mongoc_change_stream_t is a handle to a change stream. A collection
6417 change stream can be obtained using mongoc_collection_watch().
6418
6419 It is recommended to use a mongoc_change_stream_t and its functions in‐
6420 stead of a raw aggregation with a $changeStream stage. For more infor‐
6421 mation see the MongoDB Manual Entry on Change Streams.
6422
6423 Example
6424 example-collection-watch.c
6425
6426 #include <mongoc/mongoc.h>
6427
6428 int
6429 main (void)
6430 {
6431 bson_t empty = BSON_INITIALIZER;
6432 const bson_t *doc;
6433 bson_t *to_insert = BCON_NEW ("x", BCON_INT32 (1));
6434 const bson_t *err_doc;
6435 bson_error_t error;
6436 const char *uri_string;
6437 mongoc_uri_t *uri;
6438 mongoc_client_t *client;
6439 mongoc_collection_t *coll;
6440 mongoc_change_stream_t *stream;
6441 mongoc_write_concern_t *wc = mongoc_write_concern_new ();
6442 bson_t opts = BSON_INITIALIZER;
6443 bool r;
6444
6445 mongoc_init ();
6446
6447 uri_string = "mongodb://"
6448 "localhost:27017,localhost:27018,localhost:"
6449 "27019/db?replicaSet=rs0";
6450
6451 uri = mongoc_uri_new_with_error (uri_string, &error);
6452 if (!uri) {
6453 fprintf (stderr,
6454 "failed to parse URI: %s\n"
6455 "error message: %s\n",
6456 uri_string,
6457 error.message);
6458 return EXIT_FAILURE;
6459 }
6460
6461 client = mongoc_client_new_from_uri (uri);
6462 if (!client) {
6463 return EXIT_FAILURE;
6464 }
6465
6466 coll = mongoc_client_get_collection (client, "db", "coll");
6467 stream = mongoc_collection_watch (coll, &empty, NULL);
6468
6469 mongoc_write_concern_set_wmajority (wc, 10000);
6470 mongoc_write_concern_append (wc, &opts);
6471 r = mongoc_collection_insert_one (coll, to_insert, &opts, NULL, &error);
6472 if (!r) {
6473 fprintf (stderr, "Error: %s\n", error.message);
6474 return EXIT_FAILURE;
6475 }
6476
6477 while (mongoc_change_stream_next (stream, &doc)) {
6478 char *as_json = bson_as_relaxed_extended_json (doc, NULL);
6479 fprintf (stderr, "Got document: %s\n", as_json);
6480 bson_free (as_json);
6481 }
6482
6483 if (mongoc_change_stream_error_document (stream, &error, &err_doc)) {
6484 if (!bson_empty (err_doc)) {
6485 fprintf (stderr,
6486 "Server Error: %s\n",
6487 bson_as_relaxed_extended_json (err_doc, NULL));
6488 } else {
6489 fprintf (stderr, "Client Error: %s\n", error.message);
6490 }
6491 return EXIT_FAILURE;
6492 }
6493
6494 bson_destroy (to_insert);
6495 mongoc_write_concern_destroy (wc);
6496 bson_destroy (&opts);
6497 mongoc_change_stream_destroy (stream);
6498 mongoc_collection_destroy (coll);
6499 mongoc_uri_destroy (uri);
6500 mongoc_client_destroy (client);
6501 mongoc_cleanup ();
6502
6503 return EXIT_SUCCESS;
6504 }
6505
6506
6507 Starting and Resuming
6508 All watch functions accept several options to indicate where a change
6509 stream should start returning changes from: resumeAfter, startAfter,
6510 and startAtOperationTime.
6511
6512 All changes returned by mongoc_change_stream_next() include a resume
6513 token in the _id field. MongoDB 4.2 also includes an additional resume
6514 token in each "aggregate" and "getMore" command response, which points
6515 to the end of that response's batch. The current token is automatically
6516 cached by libmongoc. In the event of an error, libmongoc attempts to
6517 recreate the change stream starting where it left off by passing the
6518 cached resume token. libmongoc only attempts to resume once, but client
6519 applications can access the cached resume token with
6520 mongoc_change_stream_get_resume_token() and use it for their own resume
6521 logic by passing it as either the resumeAfter or startAfter option.
6522
6523 Additionally, change streams can start returning changes at an opera‐
6524 tion time by using the startAtOperationTime field. This can be the
6525 timestamp returned in the operationTime field of a command reply.
6526
6527 resumeAfter, startAfter, and startAtOperationTime are mutually exclu‐
6528 sive options. Setting more than one will result in a server error.
6529
6530 The following example implements custom resuming logic, persisting the
6531 resume token in a file.
6532
6533 example-resume.c
6534
6535 #include <mongoc/mongoc.h>
6536
6537 /* An example implementation of custom resume logic in a change stream.
6538 * example-resume starts a client-wide change stream and persists the resume
6539 * token in a file "resume-token.json". On restart, if "resume-token.json"
6540 * exists, the change stream starts watching after the persisted resume token.
6541 *
6542 * This behavior allows a user to exit example-resume, and restart it later
6543 * without missing any change events.
6544 */
6545 #include <unistd.h>
6546
6547 static const char *RESUME_TOKEN_PATH = "resume-token.json";
6548
6549 static bool
6550 _save_resume_token (const bson_t *doc)
6551 {
6552 FILE *file_stream;
6553 bson_iter_t iter;
6554 bson_t resume_token_doc;
6555 char *as_json = NULL;
6556 size_t as_json_len;
6557 ssize_t r, n_written;
6558 const bson_value_t *resume_token;
6559
6560 if (!bson_iter_init_find (&iter, doc, "_id")) {
6561 fprintf (stderr, "reply does not contain operationTime.");
6562 return false;
6563 }
6564 resume_token = bson_iter_value (&iter);
6565 /* store the resume token in a document, { resumeAfter: <resume token> }
6566 * which we can later append easily. */
6567 file_stream = fopen (RESUME_TOKEN_PATH, "w+");
6568 if (!file_stream) {
6569 fprintf (stderr, "failed to open %s for writing\n", RESUME_TOKEN_PATH);
6570 return false;
6571 }
6572 bson_init (&resume_token_doc);
6573 BSON_APPEND_VALUE (&resume_token_doc, "resumeAfter", resume_token);
6574 as_json = bson_as_canonical_extended_json (&resume_token_doc, &as_json_len);
6575 bson_destroy (&resume_token_doc);
6576 n_written = 0;
6577 while (n_written < as_json_len) {
6578 r = fwrite ((void *) (as_json + n_written),
6579 sizeof (char),
6580 as_json_len - n_written,
6581 file_stream);
6582 if (r == -1) {
6583 fprintf (stderr, "failed to write to %s\n", RESUME_TOKEN_PATH);
6584 bson_free (as_json);
6585 fclose (file_stream);
6586 return false;
6587 }
6588 n_written += r;
6589 }
6590
6591 bson_free (as_json);
6592 fclose (file_stream);
6593 return true;
6594 }
6595
6596 bool
6597 _load_resume_token (bson_t *opts)
6598 {
6599 bson_error_t error;
6600 bson_json_reader_t *reader;
6601 bson_t doc;
6602
6603 /* if the file does not exist, skip. */
6604 if (-1 == access (RESUME_TOKEN_PATH, R_OK)) {
6605 return true;
6606 }
6607 reader = bson_json_reader_new_from_file (RESUME_TOKEN_PATH, &error);
6608 if (!reader) {
6609 fprintf (stderr,
6610 "failed to open %s for reading: %s\n",
6611 RESUME_TOKEN_PATH,
6612 error.message);
6613 return false;
6614 }
6615
6616 bson_init (&doc);
6617 if (-1 == bson_json_reader_read (reader, &doc, &error)) {
6618 fprintf (stderr, "failed to read doc from %s\n", RESUME_TOKEN_PATH);
6619 bson_destroy (&doc);
6620 bson_json_reader_destroy (reader);
6621 return false;
6622 }
6623
6624 printf ("found cached resume token in %s, resuming change stream.\n",
6625 RESUME_TOKEN_PATH);
6626
6627 bson_concat (opts, &doc);
6628 bson_destroy (&doc);
6629 bson_json_reader_destroy (reader);
6630 return true;
6631 }
6632
6633 int
6634 main (void)
6635 {
6636 int exit_code = EXIT_FAILURE;
6637 const char *uri_string;
6638 mongoc_uri_t *uri = NULL;
6639 bson_error_t error;
6640 mongoc_client_t *client = NULL;
6641 bson_t pipeline = BSON_INITIALIZER;
6642 bson_t opts = BSON_INITIALIZER;
6643 mongoc_change_stream_t *stream = NULL;
6644 const bson_t *doc;
6645
6646 const int max_time = 30; /* max amount of time, in seconds, that
6647 mongoc_change_stream_next can block. */
6648
6649 mongoc_init ();
6650 uri_string = "mongodb://localhost:27017/db?replicaSet=rs0";
6651 uri = mongoc_uri_new_with_error (uri_string, &error);
6652 if (!uri) {
6653 fprintf (stderr,
6654 "failed to parse URI: %s\n"
6655 "error message: %s\n",
6656 uri_string,
6657 error.message);
6658 goto cleanup;
6659 }
6660
6661 client = mongoc_client_new_from_uri (uri);
6662 if (!client) {
6663 goto cleanup;
6664 }
6665
6666 if (!_load_resume_token (&opts)) {
6667 goto cleanup;
6668 }
6669 BSON_APPEND_INT64 (&opts, "maxAwaitTimeMS", max_time * 1000);
6670
6671 printf ("listening for changes on the client (max %d seconds).\n", max_time);
6672 stream = mongoc_client_watch (client, &pipeline, &opts);
6673
6674 while (mongoc_change_stream_next (stream, &doc)) {
6675 char *as_json;
6676
6677 as_json = bson_as_canonical_extended_json (doc, NULL);
6678 printf ("change received: %s\n", as_json);
6679 bson_free (as_json);
6680 if (!_save_resume_token (doc)) {
6681 goto cleanup;
6682 }
6683 }
6684
6685 exit_code = EXIT_SUCCESS;
6686
6687 cleanup:
6688 mongoc_uri_destroy (uri);
6689 bson_destroy (&pipeline);
6690 bson_destroy (&opts);
6691 mongoc_change_stream_destroy (stream);
6692 mongoc_client_destroy (client);
6693 mongoc_cleanup ();
6694 return exit_code;
6695 }
6696
6697
6698 The following example shows using startAtOperationTime to synchronize a
6699 change stream with another operation.
6700
6701 example-start-at-optime.c
6702
6703 /* An example of starting a change stream with startAtOperationTime. */
6704 #include <mongoc/mongoc.h>
6705
6706 int
6707 main (void)
6708 {
6709 int exit_code = EXIT_FAILURE;
6710 const char *uri_string;
6711 mongoc_uri_t *uri = NULL;
6712 bson_error_t error;
6713 mongoc_client_t *client = NULL;
6714 mongoc_collection_t *coll = NULL;
6715 bson_t pipeline = BSON_INITIALIZER;
6716 bson_t opts = BSON_INITIALIZER;
6717 mongoc_change_stream_t *stream = NULL;
6718 bson_iter_t iter;
6719 const bson_t *doc;
6720 bson_value_t cached_operation_time = {0};
6721 int i;
6722 bool r;
6723
6724 mongoc_init ();
6725 uri_string = "mongodb://localhost:27017/db?replicaSet=rs0";
6726 uri = mongoc_uri_new_with_error (uri_string, &error);
6727 if (!uri) {
6728 fprintf (stderr,
6729 "failed to parse URI: %s\n"
6730 "error message: %s\n",
6731 uri_string,
6732 error.message);
6733 goto cleanup;
6734 }
6735
6736 client = mongoc_client_new_from_uri (uri);
6737 if (!client) {
6738 goto cleanup;
6739 }
6740
6741 /* insert five documents. */
6742 coll = mongoc_client_get_collection (client, "db", "coll");
6743 for (i = 0; i < 5; i++) {
6744 bson_t reply;
6745 bson_t *insert_cmd = BCON_NEW ("insert",
6746 "coll",
6747 "documents",
6748 "[",
6749 "{",
6750 "x",
6751 BCON_INT64 (i),
6752 "}",
6753 "]");
6754
6755 r = mongoc_collection_write_command_with_opts (
6756 coll, insert_cmd, NULL, &reply, &error);
6757 bson_destroy (insert_cmd);
6758 if (!r) {
6759 bson_destroy (&reply);
6760 fprintf (stderr, "failed to insert: %s\n", error.message);
6761 goto cleanup;
6762 }
6763 if (i == 0) {
6764 /* cache the operation time in the first reply. */
6765 if (bson_iter_init_find (&iter, &reply, "operationTime")) {
6766 bson_value_copy (bson_iter_value (&iter), &cached_operation_time);
6767 } else {
6768 fprintf (stderr, "reply does not contain operationTime.");
6769 bson_destroy (&reply);
6770 goto cleanup;
6771 }
6772 }
6773 bson_destroy (&reply);
6774 }
6775
6776 /* start a change stream at the first returned operationTime. */
6777 BSON_APPEND_VALUE (&opts, "startAtOperationTime", &cached_operation_time);
6778 stream = mongoc_collection_watch (coll, &pipeline, &opts);
6779
6780 /* since the change stream started at the operation time of the first
6781 * insert, the five inserts are returned. */
6782 printf ("listening for changes on db.coll:\n");
6783 while (mongoc_change_stream_next (stream, &doc)) {
6784 char *as_json;
6785
6786 as_json = bson_as_canonical_extended_json (doc, NULL);
6787 printf ("change received: %s\n", as_json);
6788 bson_free (as_json);
6789 }
6790
6791 exit_code = EXIT_SUCCESS;
6792
6793 cleanup:
6794 mongoc_uri_destroy (uri);
6795 bson_destroy (&pipeline);
6796 bson_destroy (&opts);
6797 if (cached_operation_time.value_type) {
6798 bson_value_destroy (&cached_operation_time);
6799 }
6800 mongoc_change_stream_destroy (stream);
6801 mongoc_collection_destroy (coll);
6802 mongoc_client_destroy (client);
6803 mongoc_cleanup ();
6804 return exit_code;
6805 }
6806
6807
6808 mongoc_client_encryption_t
6809 Synopsis
6810 typedef struct _mongoc_client_encryption_t mongoc_client_encryption_t;
6811
6812 mongoc_client_encryption_t provides utility functions for In-Use En‐
6813 cryption.
6814
6815 Thread Safety
6816 mongoc_client_encryption_t is NOT thread-safe and should only be used
6817 in the same thread as the mongoc_client_t that is configured via
6818 mongoc_client_encryption_opts_set_keyvault_client().
6819
6820 Lifecycle
6821 The key vault client, configured via
6822 mongoc_client_encryption_opts_set_keyvault_client(), must outlive the
6823 mongoc_client_encryption_t.
6824
6825 SEE ALSO:
6826 mongoc_client_enable_auto_encryption()
6827
6828 mongoc_client_pool_enable_auto_encryption()
6829
6830 In-Use Encryption for libmongoc
6831
6832 The MongoDB Manual for Client-Side Field Level Encryption
6833
6834 The MongoDB Manual for Queryable Encryption
6835
6836
6837 mongoc_client_encryption_datakey_opts_t
6838 Synopsis
6839 typedef struct _mongoc_client_encryption_datakey_opts_t mongoc_client_encryption_datakey_opts_t;
6840
6841 Used to set options for mongoc_client_encryption_create_datakey().
6842
6843 SEE ALSO:
6844 mongoc_client_encryption_create_datakey()
6845
6846
6847 mongoc_client_encryption_rewrap_many_datakey_result_t
6848 Synopsis
6849 typedef struct _mongoc_client_encryption_rewrap_many_datakey_result_t
6850 mongoc_client_encryption_rewrap_many_datakey_result_t;
6851
6852 Used to access the result of
6853 mongoc_client_encryption_rewrap_many_datakey().
6854
6855 SEE ALSO:
6856 mongoc_client_encryption_rewrap_many_datakey()
6857
6858
6859 mongoc_client_encryption_encrypt_opts_t
6860 Synopsis
6861 typedef struct _mongoc_client_encryption_encrypt_opts_t mongoc_client_encryption_encrypt_opts_t;
6862
6863 Used to set options for mongoc_client_encryption_encrypt().
6864
6865 SEE ALSO:
6866 mongoc_client_encryption_encrypt()
6867
6868
6869 mongoc_client_encryption_encrypt_range_opts_t
6870 Synopsis
6871 typedef struct _mongoc_client_encryption_encrypt_range_opts_t mongoc_client_encryption_encrypt_range_opts_t;
6872
6873 IMPORTANT:
6874 The Range algorithm is experimental only and not intended for public
6875 use. It is subject to breaking changes. This API is part of the ex‐
6876 perimental Queryable Encryption API and may be subject to breaking
6877 changes in future releases.
6878
6879 New in version 1.24.0.
6880
6881
6882 RangeOpts specifies index options for a Queryable Encryption field sup‐
6883 porting "rangePreview" queries. Used to set options for
6884 mongoc_client_encryption_encrypt().
6885
6886 The options min, max, sparsity, and range must match the values set in
6887 the encryptedFields of the destination collection.
6888
6889 For double and decimal128 fields, min/max/precision must all be set, or
6890 all be unset.
6891
6892 SEE ALSO:
6893 mongoc_client_encryption_encrypt()
6894 mongoc_client_encryption_encrypt_opts_t
6895
6896
6897 mongoc_client_encryption_opts_t
6898 Synopsis
6899 typedef struct _mongoc_client_encryption_opts_t mongoc_client_encryption_opts_t;
6900
6901 Used to set options for mongoc_client_encryption_new().
6902
6903 SEE ALSO:
6904 mongoc_client_encryption_new()
6905
6906
6907 mongoc_client_pool_t
6908 A connection pool for multi-threaded programs. See Connection Pooling.
6909
6910 Synopsis
6911 typedef struct _mongoc_client_pool_t mongoc_client_pool_t
6912
6913 mongoc_client_pool_t is the basis for multi-threading in the MongoDB C
6914 driver. Since mongoc_client_t structures are not thread-safe, this
6915 structure is used to retrieve a new mongoc_client_t for a given thread.
6916 This structure is thread-safe, except for its destructor method,
6917 mongoc_client_pool_destroy(), which is not thread-safe and must only be
6918 called from one thread.
6919
6920 Example
6921 example-pool.c
6922
6923 /* gcc example-pool.c -o example-pool $(pkg-config --cflags --libs
6924 * libmongoc-1.0) */
6925
6926 /* ./example-pool [CONNECTION_STRING] */
6927
6928 #include <mongoc/mongoc.h>
6929 #include <pthread.h>
6930 #include <stdio.h>
6931
6932 static pthread_mutex_t mutex;
6933 static bool in_shutdown = false;
6934
6935 static void *
6936 worker (void *data)
6937 {
6938 mongoc_client_pool_t *pool = data;
6939 mongoc_client_t *client;
6940 bson_t ping = BSON_INITIALIZER;
6941 bson_error_t error;
6942 bool r;
6943
6944 BSON_APPEND_INT32 (&ping, "ping", 1);
6945
6946 while (true) {
6947 client = mongoc_client_pool_pop (pool);
6948 /* Do something with client. If you are writing an HTTP server, you
6949 * probably only want to hold onto the client for the portion of the
6950 * request performing database queries.
6951 */
6952 r = mongoc_client_command_simple (
6953 client, "admin", &ping, NULL, NULL, &error);
6954
6955 if (!r) {
6956 fprintf (stderr, "%s\n", error.message);
6957 }
6958
6959 mongoc_client_pool_push (pool, client);
6960
6961 pthread_mutex_lock (&mutex);
6962 if (in_shutdown || !r) {
6963 pthread_mutex_unlock (&mutex);
6964 break;
6965 }
6966
6967 pthread_mutex_unlock (&mutex);
6968 }
6969
6970 bson_destroy (&ping);
6971 return NULL;
6972 }
6973
6974 int
6975 main (int argc, char *argv[])
6976 {
6977 const char *uri_string = "mongodb://127.0.0.1/?appname=pool-example";
6978 mongoc_uri_t *uri;
6979 bson_error_t error;
6980 mongoc_client_pool_t *pool;
6981 pthread_t threads[10];
6982 unsigned i;
6983 void *ret;
6984
6985 pthread_mutex_init (&mutex, NULL);
6986 mongoc_init ();
6987
6988 if (argc > 1) {
6989 uri_string = argv[1];
6990 }
6991
6992 uri = mongoc_uri_new_with_error (uri_string, &error);
6993 if (!uri) {
6994 fprintf (stderr,
6995 "failed to parse URI: %s\n"
6996 "error message: %s\n",
6997 uri_string,
6998 error.message);
6999 return EXIT_FAILURE;
7000 }
7001
7002 pool = mongoc_client_pool_new (uri);
7003 mongoc_client_pool_set_error_api (pool, 2);
7004
7005 for (i = 0; i < 10; i++) {
7006 pthread_create (&threads[i], NULL, worker, pool);
7007 }
7008
7009 sleep (10);
7010 pthread_mutex_lock (&mutex);
7011 in_shutdown = true;
7012 pthread_mutex_unlock (&mutex);
7013
7014 for (i = 0; i < 10; i++) {
7015 pthread_join (threads[i], &ret);
7016 }
7017
7018 mongoc_client_pool_destroy (pool);
7019 mongoc_uri_destroy (uri);
7020
7021 mongoc_cleanup ();
7022
7023 return EXIT_SUCCESS;
7024 }
7025
7026
7027 mongoc_client_session_t
7028 Use a session for a sequence of operations, optionally with causal con‐
7029 sistency. See the MongoDB Manual Entry for Causal Consistency.
7030
7031 Synopsis
7032 Start a session with mongoc_client_start_session(), use the session for
7033 a sequence of operations and multi-document transactions, then free it
7034 with mongoc_client_session_destroy(). Any mongoc_cursor_t or
7035 mongoc_change_stream_t using a session must be destroyed before the
7036 session, and a session must be destroyed before the mongoc_client_t it
7037 came from.
7038
7039 By default, sessions are causally consistent. To disable causal consis‐
7040 tency, before starting a session create a mongoc_session_opt_t with
7041 mongoc_session_opts_new() and call
7042 mongoc_session_opts_set_causal_consistency(), then free the struct with
7043 mongoc_session_opts_destroy().
7044
7045 Unacknowledged writes are prohibited with sessions.
7046
7047 A mongoc_client_session_t must be used by only one thread at a time.
7048 Due to session pooling, mongoc_client_start_session() may return a ses‐
7049 sion that has been idle for some time and is about to be closed after
7050 its idle timeout. Use the session within one minute of acquiring it to
7051 refresh the session and avoid a timeout.
7052
7053 Example
7054 example-session.c
7055
7056 /* gcc example-session.c -o example-session \
7057 * $(pkg-config --cflags --libs libmongoc-1.0) */
7058
7059 /* ./example-session [CONNECTION_STRING] */
7060
7061 #include <stdio.h>
7062 #include <mongoc/mongoc.h>
7063
7064
7065 int
7066 main (int argc, char *argv[])
7067 {
7068 int exit_code = EXIT_FAILURE;
7069
7070 mongoc_client_t *client = NULL;
7071 const char *uri_string = "mongodb://127.0.0.1/?appname=session-example";
7072 mongoc_uri_t *uri = NULL;
7073 mongoc_client_session_t *client_session = NULL;
7074 mongoc_collection_t *collection = NULL;
7075 bson_error_t error;
7076 bson_t *selector = NULL;
7077 bson_t *update = NULL;
7078 bson_t *update_opts = NULL;
7079 bson_t *find_opts = NULL;
7080 mongoc_read_prefs_t *secondary = NULL;
7081 mongoc_cursor_t *cursor = NULL;
7082 const bson_t *doc;
7083 char *str;
7084 bool r;
7085
7086 mongoc_init ();
7087
7088 if (argc > 1) {
7089 uri_string = argv[1];
7090 }
7091
7092 uri = mongoc_uri_new_with_error (uri_string, &error);
7093 if (!uri) {
7094 fprintf (stderr,
7095 "failed to parse URI: %s\n"
7096 "error message: %s\n",
7097 uri_string,
7098 error.message);
7099 goto done;
7100 }
7101
7102 client = mongoc_client_new_from_uri (uri);
7103 if (!client) {
7104 goto done;
7105 }
7106
7107 mongoc_client_set_error_api (client, 2);
7108
7109 /* pass NULL for options - by default the session is causally consistent */
7110 client_session = mongoc_client_start_session (client, NULL, &error);
7111 if (!client_session) {
7112 fprintf (stderr, "Failed to start session: %s\n", error.message);
7113 goto done;
7114 }
7115
7116 collection = mongoc_client_get_collection (client, "test", "collection");
7117 selector = BCON_NEW ("_id", BCON_INT32 (1));
7118 update = BCON_NEW ("$inc", "{", "x", BCON_INT32 (1), "}");
7119 update_opts = bson_new ();
7120 if (!mongoc_client_session_append (client_session, update_opts, &error)) {
7121 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
7122 goto done;
7123 }
7124
7125 r = mongoc_collection_update_one (
7126 collection, selector, update, update_opts, NULL /* reply */, &error);
7127
7128 if (!r) {
7129 fprintf (stderr, "Update failed: %s\n", error.message);
7130 goto done;
7131 }
7132
7133 bson_destroy (selector);
7134 selector = BCON_NEW ("_id", BCON_INT32 (1));
7135 secondary = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
7136
7137 find_opts = BCON_NEW ("maxTimeMS", BCON_INT32 (2000));
7138 if (!mongoc_client_session_append (client_session, find_opts, &error)) {
7139 fprintf (stderr, "Could not add session to opts: %s\n", error.message);
7140 goto done;
7141 };
7142
7143 /* read from secondary. since we're in a causally consistent session, the
7144 * data is guaranteed to reflect the update we did on the primary. the query
7145 * blocks waiting for the secondary to catch up, if necessary, or times out
7146 * and fails after 2000 ms.
7147 */
7148 cursor = mongoc_collection_find_with_opts (
7149 collection, selector, find_opts, secondary);
7150
7151 while (mongoc_cursor_next (cursor, &doc)) {
7152 str = bson_as_json (doc, NULL);
7153 fprintf (stdout, "%s\n", str);
7154 bson_free (str);
7155 }
7156
7157 if (mongoc_cursor_error (cursor, &error)) {
7158 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7159 goto done;
7160 }
7161
7162 exit_code = EXIT_SUCCESS;
7163
7164 done:
7165 if (find_opts) {
7166 bson_destroy (find_opts);
7167 }
7168 if (update) {
7169 bson_destroy (update);
7170 }
7171 if (selector) {
7172 bson_destroy (selector);
7173 }
7174 if (update_opts) {
7175 bson_destroy (update_opts);
7176 }
7177 if (secondary) {
7178 mongoc_read_prefs_destroy (secondary);
7179 }
7180 /* destroy cursor, collection, session before the client they came from */
7181 if (cursor) {
7182 mongoc_cursor_destroy (cursor);
7183 }
7184 if (collection) {
7185 mongoc_collection_destroy (collection);
7186 }
7187 if (client_session) {
7188 mongoc_client_session_destroy (client_session);
7189 }
7190 if (uri) {
7191 mongoc_uri_destroy (uri);
7192 }
7193 if (client) {
7194 mongoc_client_destroy (client);
7195 }
7196
7197 mongoc_cleanup ();
7198
7199 return exit_code;
7200 }
7201
7202
7203 mongoc_client_session_with_transaction_cb_t
7204 Synopsis
7205 typedef bool (*mongoc_client_session_with_transaction_cb_t) (
7206 mongoc_client_session_t *session,
7207 void *ctx,
7208 bson_t **reply,
7209 bson_error_t *error);
7210
7211 Provide this callback to mongoc_client_session_with_transaction(). The
7212 callback should run a sequence of operations meant to be contained
7213 within a transaction. The callback should not attempt to start or com‐
7214 mit transactions.
7215
7216 Parameters
7217 • session: A mongoc_client_session_t.
7218
7219 • ctx: A void* set to the the user-provided ctx passed to
7220 mongoc_client_session_with_transaction().
7221
7222 • reply: An optional location for a bson_t or NULL. The callback should
7223 set this if it runs any operations against the server and receives
7224 replies.
7225
7226 • error: A bson_error_t. The callback should set this if it receives
7227 any errors while running operations against the server.
7228
7229 Return
7230 Returns true for success and false on failure. If cb returns false then
7231 it should also set error.
7232
7233 SEE ALSO:
7234 mongoc_client_session_with_transaction()
7235
7236
7237 mongoc_client_t
7238 A single-threaded MongoDB connection. See Connection Pooling.
7239
7240 Synopsis
7241 typedef struct _mongoc_client_t mongoc_client_t;
7242
7243 typedef mongoc_stream_t *(*mongoc_stream_initiator_t) (
7244 const mongoc_uri_t *uri,
7245 const mongoc_host_list_t *host,
7246 void *user_data,
7247 bson_error_t *error);
7248
7249 mongoc_client_t is an opaque type that provides access to a MongoDB
7250 server, replica set, or sharded cluster. It maintains management of un‐
7251 derlying sockets and routing to individual nodes based on
7252 mongoc_read_prefs_t or mongoc_write_concern_t.
7253
7254 Streams
7255 The underlying transport for a given client can be customized, wrapped
7256 or replaced by any implementation that fulfills mongoc_stream_t. A cus‐
7257 tom transport can be set with mongoc_client_set_stream_initiator().
7258
7259 Thread Safety
7260 mongoc_client_t is NOT thread-safe and should only be used from one
7261 thread at a time. When used in multi-threaded scenarios, it is recom‐
7262 mended that you use the thread-safe mongoc_client_pool_t to retrieve a
7263 mongoc_client_t for your thread.
7264
7265 Example
7266 example-client.c
7267
7268 /* gcc example-client.c -o example-client $(pkg-config --cflags --libs
7269 * libmongoc-1.0) */
7270
7271 /* ./example-client [CONNECTION_STRING [COLLECTION_NAME]] */
7272
7273 #include <mongoc/mongoc.h>
7274 #include <stdio.h>
7275 #include <stdlib.h>
7276
7277 int
7278 main (int argc, char *argv[])
7279 {
7280 mongoc_client_t *client;
7281 mongoc_collection_t *collection;
7282 mongoc_cursor_t *cursor;
7283 bson_error_t error;
7284 const bson_t *doc;
7285 const char *collection_name = "test";
7286 bson_t query;
7287 char *str;
7288 const char *uri_string = "mongodb://127.0.0.1/?appname=client-example";
7289 mongoc_uri_t *uri;
7290
7291 mongoc_init ();
7292 if (argc > 1) {
7293 uri_string = argv[1];
7294 }
7295
7296 if (argc > 2) {
7297 collection_name = argv[2];
7298 }
7299
7300 uri = mongoc_uri_new_with_error (uri_string, &error);
7301 if (!uri) {
7302 fprintf (stderr,
7303 "failed to parse URI: %s\n"
7304 "error message: %s\n",
7305 uri_string,
7306 error.message);
7307 return EXIT_FAILURE;
7308 }
7309
7310 client = mongoc_client_new_from_uri (uri);
7311 if (!client) {
7312 return EXIT_FAILURE;
7313 }
7314
7315 mongoc_client_set_error_api (client, 2);
7316
7317 bson_init (&query);
7318 collection = mongoc_client_get_collection (client, "test", collection_name);
7319 cursor = mongoc_collection_find_with_opts (
7320 collection,
7321 &query,
7322 NULL, /* additional options */
7323 NULL); /* read prefs, NULL for default */
7324
7325 while (mongoc_cursor_next (cursor, &doc)) {
7326 str = bson_as_canonical_extended_json (doc, NULL);
7327 fprintf (stdout, "%s\n", str);
7328 bson_free (str);
7329 }
7330
7331 if (mongoc_cursor_error (cursor, &error)) {
7332 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7333 return EXIT_FAILURE;
7334 }
7335
7336 bson_destroy (&query);
7337 mongoc_cursor_destroy (cursor);
7338 mongoc_collection_destroy (collection);
7339 mongoc_uri_destroy (uri);
7340 mongoc_client_destroy (client);
7341 mongoc_cleanup ();
7342
7343 return EXIT_SUCCESS;
7344 }
7345
7346
7347 mongoc_collection_t
7348 Synopsis
7349 typedef struct _mongoc_collection_t mongoc_collection_t;
7350
7351 mongoc_collection_t provides access to a MongoDB collection. This han‐
7352 dle is useful for actions for most CRUD operations, I.e. insert, up‐
7353 date, delete, find, etc.
7354
7355 Read Preferences and Write Concerns
7356 Read preferences and write concerns are inherited from the parent
7357 client. They can be overridden by set_* commands if so desired.
7358
7359 mongoc_cursor_t
7360 Client-side cursor abstraction
7361
7362 Synopsis
7363 typedef struct _mongoc_cursor_t mongoc_cursor_t;
7364
7365 mongoc_cursor_t provides access to a MongoDB query cursor. It wraps up
7366 the wire protocol negotiation required to initiate a query and retrieve
7367 an unknown number of documents.
7368
7369 Common cursor operations include:
7370
7371 • Determine which host we've connected to with
7372 mongoc_cursor_get_host().
7373
7374 • Retrieve more records with repeated calls to mongoc_cursor_next().
7375
7376 • Clone a query to repeat execution at a later point with
7377 mongoc_cursor_clone().
7378
7379 • Test for errors with mongoc_cursor_error().
7380
7381 Cursors are lazy, meaning that no connection is established and no net‐
7382 work traffic occurs until the first call to mongoc_cursor_next().
7383
7384 Thread Safety
7385 mongoc_cursor_t is NOT thread safe. It may only be used from within the
7386 thread in which it was created.
7387
7388 Example
7389 Query MongoDB and iterate results
7390
7391 /* gcc example-client.c -o example-client $(pkg-config --cflags --libs
7392 * libmongoc-1.0) */
7393
7394 /* ./example-client [CONNECTION_STRING [COLLECTION_NAME]] */
7395
7396 #include <mongoc/mongoc.h>
7397 #include <stdio.h>
7398 #include <stdlib.h>
7399
7400 int
7401 main (int argc, char *argv[])
7402 {
7403 mongoc_client_t *client;
7404 mongoc_collection_t *collection;
7405 mongoc_cursor_t *cursor;
7406 bson_error_t error;
7407 const bson_t *doc;
7408 const char *collection_name = "test";
7409 bson_t query;
7410 char *str;
7411 const char *uri_string = "mongodb://127.0.0.1/?appname=client-example";
7412 mongoc_uri_t *uri;
7413
7414 mongoc_init ();
7415 if (argc > 1) {
7416 uri_string = argv[1];
7417 }
7418
7419 if (argc > 2) {
7420 collection_name = argv[2];
7421 }
7422
7423 uri = mongoc_uri_new_with_error (uri_string, &error);
7424 if (!uri) {
7425 fprintf (stderr,
7426 "failed to parse URI: %s\n"
7427 "error message: %s\n",
7428 uri_string,
7429 error.message);
7430 return EXIT_FAILURE;
7431 }
7432
7433 client = mongoc_client_new_from_uri (uri);
7434 if (!client) {
7435 return EXIT_FAILURE;
7436 }
7437
7438 mongoc_client_set_error_api (client, 2);
7439
7440 bson_init (&query);
7441 collection = mongoc_client_get_collection (client, "test", collection_name);
7442 cursor = mongoc_collection_find_with_opts (
7443 collection,
7444 &query,
7445 NULL, /* additional options */
7446 NULL); /* read prefs, NULL for default */
7447
7448 while (mongoc_cursor_next (cursor, &doc)) {
7449 str = bson_as_canonical_extended_json (doc, NULL);
7450 fprintf (stdout, "%s\n", str);
7451 bson_free (str);
7452 }
7453
7454 if (mongoc_cursor_error (cursor, &error)) {
7455 fprintf (stderr, "Cursor Failure: %s\n", error.message);
7456 return EXIT_FAILURE;
7457 }
7458
7459 bson_destroy (&query);
7460 mongoc_cursor_destroy (cursor);
7461 mongoc_collection_destroy (collection);
7462 mongoc_uri_destroy (uri);
7463 mongoc_client_destroy (client);
7464 mongoc_cleanup ();
7465
7466 return EXIT_SUCCESS;
7467 }
7468
7469
7470 mongoc_database_t
7471 MongoDB Database Abstraction
7472
7473 Synopsis
7474 typedef struct _mongoc_database_t mongoc_database_t;
7475
7476 mongoc_database_t provides access to a MongoDB database. This handle is
7477 useful for actions a particular database object. It is not a container
7478 for mongoc_collection_t structures.
7479
7480 Read preferences and write concerns are inherited from the parent
7481 client. They can be overridden with mongoc_database_set_read_prefs()
7482 and mongoc_database_set_write_concern().
7483
7484 Examples
7485 #include <mongoc/mongoc.h>
7486
7487 int
7488 main (int argc, char *argv[])
7489 {
7490 mongoc_database_t *database;
7491 mongoc_client_t *client;
7492
7493 mongoc_init ();
7494
7495 client = mongoc_client_new ("mongodb://localhost/");
7496 database = mongoc_client_get_database (client, "test");
7497
7498 mongoc_database_destroy (database);
7499 mongoc_client_destroy (client);
7500
7501 mongoc_cleanup ();
7502
7503 return 0;
7504 }
7505
7506 mongoc_delete_flags_t
7507 WARNING:
7508 Deprecated since version 1.9.0: These flags are deprecated and
7509 should not be used in new code.
7510
7511 Please use mongoc_collection_delete_one() or
7512 mongoc_collection_delete_many() in new code.
7513
7514
7515 Synopsis
7516 typedef enum {
7517 MONGOC_DELETE_NONE = 0,
7518 MONGOC_DELETE_SINGLE_REMOVE = 1 << 0,
7519 } mongoc_delete_flags_t;
7520
7521 Flags for deletion operations
7522
7523 mongoc_find_and_modify_opts_t
7524 find_and_modify abstraction
7525
7526 Synopsis
7527 mongoc_find_and_modify_opts_t is a builder interface to construct the
7528 findAndModify command.
7529
7530 It was created to be able to accommodate new arguments to the findAnd‐
7531 Modify command.
7532
7533 As of MongoDB 3.2, the mongoc_write_concern_t specified on the
7534 mongoc_collection_t will be used, if any.
7535
7536 Example
7537 flags.c
7538
7539 void
7540 fam_flags (mongoc_collection_t *collection)
7541 {
7542 mongoc_find_and_modify_opts_t *opts;
7543 bson_t reply;
7544 bson_error_t error;
7545 bson_t query = BSON_INITIALIZER;
7546 bson_t *update;
7547 bool success;
7548
7549
7550 /* Find Zlatan Ibrahimovic, the striker */
7551 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7552 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7553 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7554 BSON_APPEND_INT32 (&query, "age", 34);
7555 BSON_APPEND_INT32 (
7556 &query, "goals", (16 + 35 + 23 + 57 + 16 + 14 + 28 + 84) + (1 + 6 + 62));
7557
7558 /* Add his football position */
7559 update = BCON_NEW ("$set", "{", "position", BCON_UTF8 ("striker"), "}");
7560
7561 opts = mongoc_find_and_modify_opts_new ();
7562
7563 mongoc_find_and_modify_opts_set_update (opts, update);
7564
7565 /* Create the document if it didn't exist, and return the updated document */
7566 mongoc_find_and_modify_opts_set_flags (
7567 opts, MONGOC_FIND_AND_MODIFY_UPSERT | MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7568
7569 success = mongoc_collection_find_and_modify_with_opts (
7570 collection, &query, opts, &reply, &error);
7571
7572 if (success) {
7573 char *str;
7574
7575 str = bson_as_canonical_extended_json (&reply, NULL);
7576 printf ("%s\n", str);
7577 bson_free (str);
7578 } else {
7579 fprintf (
7580 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7581 }
7582
7583 bson_destroy (&reply);
7584 bson_destroy (update);
7585 bson_destroy (&query);
7586 mongoc_find_and_modify_opts_destroy (opts);
7587 }
7588
7589
7590 bypass.c
7591
7592 void
7593 fam_bypass (mongoc_collection_t *collection)
7594 {
7595 mongoc_find_and_modify_opts_t *opts;
7596 bson_t reply;
7597 bson_t *update;
7598 bson_error_t error;
7599 bson_t query = BSON_INITIALIZER;
7600 bool success;
7601
7602
7603 /* Find Zlatan Ibrahimovic, the striker */
7604 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7605 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7606 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7607
7608 /* Bump his age */
7609 update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}");
7610
7611 opts = mongoc_find_and_modify_opts_new ();
7612 mongoc_find_and_modify_opts_set_update (opts, update);
7613 /* He can still play, even though he is pretty old. */
7614 mongoc_find_and_modify_opts_set_bypass_document_validation (opts, true);
7615
7616 success = mongoc_collection_find_and_modify_with_opts (
7617 collection, &query, opts, &reply, &error);
7618
7619 if (success) {
7620 char *str;
7621
7622 str = bson_as_canonical_extended_json (&reply, NULL);
7623 printf ("%s\n", str);
7624 bson_free (str);
7625 } else {
7626 fprintf (
7627 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7628 }
7629
7630 bson_destroy (&reply);
7631 bson_destroy (update);
7632 bson_destroy (&query);
7633 mongoc_find_and_modify_opts_destroy (opts);
7634 }
7635
7636
7637 update.c
7638
7639 void
7640 fam_update (mongoc_collection_t *collection)
7641 {
7642 mongoc_find_and_modify_opts_t *opts;
7643 bson_t *update;
7644 bson_t reply;
7645 bson_error_t error;
7646 bson_t query = BSON_INITIALIZER;
7647 bool success;
7648
7649
7650 /* Find Zlatan Ibrahimovic */
7651 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7652 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7653
7654 /* Make him a book author */
7655 update = BCON_NEW ("$set", "{", "author", BCON_BOOL (true), "}");
7656
7657 opts = mongoc_find_and_modify_opts_new ();
7658 /* Note that the document returned is the _previous_ version of the document
7659 * To fetch the modified new version, use
7660 * mongoc_find_and_modify_opts_set_flags (opts,
7661 * MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7662 */
7663 mongoc_find_and_modify_opts_set_update (opts, update);
7664
7665 success = mongoc_collection_find_and_modify_with_opts (
7666 collection, &query, opts, &reply, &error);
7667
7668 if (success) {
7669 char *str;
7670
7671 str = bson_as_canonical_extended_json (&reply, NULL);
7672 printf ("%s\n", str);
7673 bson_free (str);
7674 } else {
7675 fprintf (
7676 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7677 }
7678
7679 bson_destroy (&reply);
7680 bson_destroy (update);
7681 bson_destroy (&query);
7682 mongoc_find_and_modify_opts_destroy (opts);
7683 }
7684
7685
7686 fields.c
7687
7688 void
7689 fam_fields (mongoc_collection_t *collection)
7690 {
7691 mongoc_find_and_modify_opts_t *opts;
7692 bson_t fields = BSON_INITIALIZER;
7693 bson_t *update;
7694 bson_t reply;
7695 bson_error_t error;
7696 bson_t query = BSON_INITIALIZER;
7697 bool success;
7698
7699
7700 /* Find Zlatan Ibrahimovic */
7701 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7702 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7703
7704 /* Return his goal tally */
7705 BSON_APPEND_INT32 (&fields, "goals", 1);
7706
7707 /* Bump his goal tally */
7708 update = BCON_NEW ("$inc", "{", "goals", BCON_INT32 (1), "}");
7709
7710 opts = mongoc_find_and_modify_opts_new ();
7711 mongoc_find_and_modify_opts_set_update (opts, update);
7712 mongoc_find_and_modify_opts_set_fields (opts, &fields);
7713 /* Return the new tally */
7714 mongoc_find_and_modify_opts_set_flags (opts,
7715 MONGOC_FIND_AND_MODIFY_RETURN_NEW);
7716
7717 success = mongoc_collection_find_and_modify_with_opts (
7718 collection, &query, opts, &reply, &error);
7719
7720 if (success) {
7721 char *str;
7722
7723 str = bson_as_canonical_extended_json (&reply, NULL);
7724 printf ("%s\n", str);
7725 bson_free (str);
7726 } else {
7727 fprintf (
7728 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7729 }
7730
7731 bson_destroy (&reply);
7732 bson_destroy (update);
7733 bson_destroy (&fields);
7734 bson_destroy (&query);
7735 mongoc_find_and_modify_opts_destroy (opts);
7736 }
7737
7738
7739 sort.c
7740
7741 void
7742 fam_sort (mongoc_collection_t *collection)
7743 {
7744 mongoc_find_and_modify_opts_t *opts;
7745 bson_t *update;
7746 bson_t sort = BSON_INITIALIZER;
7747 bson_t reply;
7748 bson_error_t error;
7749 bson_t query = BSON_INITIALIZER;
7750 bool success;
7751
7752
7753 /* Find all users with the lastname Ibrahimovic */
7754 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7755
7756 /* Sort by age (descending) */
7757 BSON_APPEND_INT32 (&sort, "age", -1);
7758
7759 /* Bump his goal tally */
7760 update = BCON_NEW ("$set", "{", "oldest", BCON_BOOL (true), "}");
7761
7762 opts = mongoc_find_and_modify_opts_new ();
7763 mongoc_find_and_modify_opts_set_update (opts, update);
7764 mongoc_find_and_modify_opts_set_sort (opts, &sort);
7765
7766 success = mongoc_collection_find_and_modify_with_opts (
7767 collection, &query, opts, &reply, &error);
7768
7769 if (success) {
7770 char *str;
7771
7772 str = bson_as_canonical_extended_json (&reply, NULL);
7773 printf ("%s\n", str);
7774 bson_free (str);
7775 } else {
7776 fprintf (
7777 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7778 }
7779
7780 bson_destroy (&reply);
7781 bson_destroy (update);
7782 bson_destroy (&sort);
7783 bson_destroy (&query);
7784 mongoc_find_and_modify_opts_destroy (opts);
7785 }
7786
7787
7788 opts.c
7789
7790 void
7791 fam_opts (mongoc_collection_t *collection)
7792 {
7793 mongoc_find_and_modify_opts_t *opts;
7794 bson_t reply;
7795 bson_t *update;
7796 bson_error_t error;
7797 bson_t query = BSON_INITIALIZER;
7798 mongoc_write_concern_t *wc;
7799 bson_t extra = BSON_INITIALIZER;
7800 bool success;
7801
7802
7803 /* Find Zlatan Ibrahimovic, the striker */
7804 BSON_APPEND_UTF8 (&query, "firstname", "Zlatan");
7805 BSON_APPEND_UTF8 (&query, "lastname", "Ibrahimovic");
7806 BSON_APPEND_UTF8 (&query, "profession", "Football player");
7807
7808 /* Bump his age */
7809 update = BCON_NEW ("$inc", "{", "age", BCON_INT32 (1), "}");
7810
7811 opts = mongoc_find_and_modify_opts_new ();
7812 mongoc_find_and_modify_opts_set_update (opts, update);
7813
7814 /* Abort if the operation takes too long. */
7815 mongoc_find_and_modify_opts_set_max_time_ms (opts, 100);
7816
7817 /* Set write concern w: 2 */
7818 wc = mongoc_write_concern_new ();
7819 mongoc_write_concern_set_w (wc, 2);
7820 mongoc_write_concern_append (wc, &extra);
7821
7822 /* Some future findAndModify option the driver doesn't support conveniently
7823 */
7824 BSON_APPEND_INT32 (&extra, "futureOption", 42);
7825 mongoc_find_and_modify_opts_append (opts, &extra);
7826
7827 success = mongoc_collection_find_and_modify_with_opts (
7828 collection, &query, opts, &reply, &error);
7829
7830 if (success) {
7831 char *str;
7832
7833 str = bson_as_canonical_extended_json (&reply, NULL);
7834 printf ("%s\n", str);
7835 bson_free (str);
7836 } else {
7837 fprintf (
7838 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7839 }
7840
7841 bson_destroy (&reply);
7842 bson_destroy (&extra);
7843 bson_destroy (update);
7844 bson_destroy (&query);
7845 mongoc_write_concern_destroy (wc);
7846 mongoc_find_and_modify_opts_destroy (opts);
7847 }
7848
7849
7850 fam.c
7851
7852 int
7853 main (void)
7854 {
7855 mongoc_collection_t *collection;
7856 mongoc_database_t *database;
7857 mongoc_client_t *client;
7858 const char *uri_string =
7859 "mongodb://localhost:27017/admin?appname=find-and-modify-opts-example";
7860 mongoc_uri_t *uri;
7861 bson_error_t error;
7862 bson_t *options;
7863
7864 mongoc_init ();
7865
7866 uri = mongoc_uri_new_with_error (uri_string, &error);
7867 if (!uri) {
7868 fprintf (stderr,
7869 "failed to parse URI: %s\n"
7870 "error message: %s\n",
7871 uri_string,
7872 error.message);
7873 return EXIT_FAILURE;
7874 }
7875
7876 client = mongoc_client_new_from_uri (uri);
7877 if (!client) {
7878 return EXIT_FAILURE;
7879 }
7880
7881 mongoc_client_set_error_api (client, 2);
7882 database = mongoc_client_get_database (client, "databaseName");
7883
7884 options = BCON_NEW ("validator",
7885 "{",
7886 "age",
7887 "{",
7888 "$lte",
7889 BCON_INT32 (34),
7890 "}",
7891 "}",
7892 "validationAction",
7893 BCON_UTF8 ("error"),
7894 "validationLevel",
7895 BCON_UTF8 ("moderate"));
7896
7897 collection = mongoc_database_create_collection (
7898 database, "collectionName", options, &error);
7899 if (!collection) {
7900 fprintf (
7901 stderr, "Got error: \"%s\" on line %d\n", error.message, __LINE__);
7902 return EXIT_FAILURE;
7903 }
7904
7905 fam_flags (collection);
7906 fam_bypass (collection);
7907 fam_update (collection);
7908 fam_fields (collection);
7909 fam_opts (collection);
7910 fam_sort (collection);
7911
7912 mongoc_collection_drop (collection, NULL);
7913 bson_destroy (options);
7914 mongoc_uri_destroy (uri);
7915 mongoc_database_destroy (database);
7916 mongoc_collection_destroy (collection);
7917 mongoc_client_destroy (client);
7918
7919 mongoc_cleanup ();
7920 return EXIT_SUCCESS;
7921 }
7922
7923
7924 Outputs:
7925
7926 {
7927 "lastErrorObject": {
7928 "updatedExisting": false,
7929 "n": 1,
7930 "upserted": {
7931 "$oid": "56562a99d13e6d86239c7b00"
7932 }
7933 },
7934 "value": {
7935 "_id": {
7936 "$oid": "56562a99d13e6d86239c7b00"
7937 },
7938 "age": 34,
7939 "firstname": "Zlatan",
7940 "goals": 342,
7941 "lastname": "Ibrahimovic",
7942 "profession": "Football player",
7943 "position": "striker"
7944 },
7945 "ok": 1
7946 }
7947 {
7948 "lastErrorObject": {
7949 "updatedExisting": true,
7950 "n": 1
7951 },
7952 "value": {
7953 "_id": {
7954 "$oid": "56562a99d13e6d86239c7b00"
7955 },
7956 "age": 34,
7957 "firstname": "Zlatan",
7958 "goals": 342,
7959 "lastname": "Ibrahimovic",
7960 "profession": "Football player",
7961 "position": "striker"
7962 },
7963 "ok": 1
7964 }
7965 {
7966 "lastErrorObject": {
7967 "updatedExisting": true,
7968 "n": 1
7969 },
7970 "value": {
7971 "_id": {
7972 "$oid": "56562a99d13e6d86239c7b00"
7973 },
7974 "age": 35,
7975 "firstname": "Zlatan",
7976 "goals": 342,
7977 "lastname": "Ibrahimovic",
7978 "profession": "Football player",
7979 "position": "striker"
7980 },
7981 "ok": 1
7982 }
7983 {
7984 "lastErrorObject": {
7985 "updatedExisting": true,
7986 "n": 1
7987 },
7988 "value": {
7989 "_id": {
7990 "$oid": "56562a99d13e6d86239c7b00"
7991 },
7992 "goals": 343
7993 },
7994 "ok": 1
7995 }
7996 {
7997 "lastErrorObject": {
7998 "updatedExisting": true,
7999 "n": 1
8000 },
8001 "value": {
8002 "_id": {
8003 "$oid": "56562a99d13e6d86239c7b00"
8004 },
8005 "age": 35,
8006 "firstname": "Zlatan",
8007 "goals": 343,
8008 "lastname": "Ibrahimovic",
8009 "profession": "Football player",
8010 "position": "striker",
8011 "author": true
8012 },
8013 "ok": 1
8014 }
8015
8016 mongoc_gridfs_file_list_t
8017 Synopsis
8018 #include <mongoc/mongoc.h>
8019
8020 typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t;
8021
8022 Description
8023 mongoc_gridfs_file_list_t provides a gridfs file list abstraction. It
8024 provides iteration and basic marshalling on top of a regular
8025 mongoc_collection_find_with_opts() style query. In interface, it's
8026 styled after mongoc_cursor_t.
8027
8028 Example
8029 mongoc_gridfs_file_list_t *list;
8030 mongoc_gridfs_file_t *file;
8031
8032 list = mongoc_gridfs_find (gridfs, query);
8033
8034 while ((file = mongoc_gridfs_file_list_next (list))) {
8035 do_something (file);
8036
8037 mongoc_gridfs_file_destroy (file);
8038 }
8039
8040 mongoc_gridfs_file_list_destroy (list);
8041
8042 mongoc_gridfs_file_opt_t
8043 Synopsis
8044 typedef struct {
8045 const char *md5;
8046 const char *filename;
8047 const char *content_type;
8048 const bson_t *aliases;
8049 const bson_t *metadata;
8050 uint32_t chunk_size;
8051 } mongoc_gridfs_file_opt_t;
8052
8053 Description
8054 This structure contains options that can be set on a
8055 mongoc_gridfs_file_t. It can be used by various functions when creating
8056 a new gridfs file.
8057
8058 mongoc_gridfs_file_t
8059 Synopsis
8060 typedef struct _mongoc_gridfs_file_t mongoc_gridfs_file_t;
8061
8062 Description
8063 This structure provides a MongoDB GridFS file abstraction. It provides
8064 several APIs.
8065
8066 • readv, writev, seek, and tell.
8067
8068 • General file metadata such as filename and length.
8069
8070 • GridFS metadata such as md5, filename, content_type, aliases, meta‐
8071 data, chunk_size, and upload_date.
8072
8073 Thread Safety
8074 This structure is NOT thread-safe and should only be used from one
8075 thread at a time.
8076
8077 Related
8078 • mongoc_client_t
8079
8080 • mongoc_gridfs_t
8081
8082 • mongoc_gridfs_file_list_t
8083
8084 • mongoc_gridfs_file_opt_t
8085
8086 mongoc_gridfs_bucket_t
8087 Synopsis
8088 #include <mongoc/mongoc.h>
8089
8090 typedef struct _mongoc_gridfs_bucket_t mongoc_gridfs_bucket_t;
8091
8092 Description
8093 mongoc_gridfs_bucket_t provides a spec-compliant MongoDB GridFS imple‐
8094 mentation, superseding mongoc_gridfs_t. See the GridFS MongoDB documen‐
8095 tation.
8096
8097 Thread Safety
8098 mongoc_gridfs_bucket_t is NOT thread-safe and should only be used in
8099 the same thread as the owning mongoc_client_t.
8100
8101 Lifecycle
8102 It is an error to free a mongoc_gridfs_bucket_t before freeing all de‐
8103 rived instances of mongoc_stream_t. The owning mongoc_client_t must
8104 outlive the mongoc_gridfs_bucket_t.
8105
8106 Example
8107 example-gridfs-bucket.c
8108
8109 #include <stdio.h>
8110 #include <stdlib.h>
8111
8112 #include <mongoc/mongoc.h>
8113
8114 int
8115 main (int argc, char *argv[])
8116 {
8117 const char *uri_string =
8118 "mongodb://localhost:27017/?appname=new-gridfs-example";
8119 mongoc_client_t *client;
8120 mongoc_database_t *db;
8121 mongoc_stream_t *file_stream;
8122 mongoc_gridfs_bucket_t *bucket;
8123 mongoc_cursor_t *cursor;
8124 bson_t filter;
8125 bool res;
8126 bson_value_t file_id;
8127 bson_error_t error;
8128 const bson_t *doc;
8129 char *str;
8130 mongoc_init ();
8131
8132 if (argc != 3) {
8133 fprintf (stderr, "usage: %s SOURCE_FILE_PATH FILE_COPY_PATH\n", argv[0]);
8134 return EXIT_FAILURE;
8135 }
8136
8137 /* 1. Make a bucket. */
8138 client = mongoc_client_new (uri_string);
8139 db = mongoc_client_get_database (client, "test");
8140 bucket = mongoc_gridfs_bucket_new (db, NULL, NULL, &error);
8141 if (!bucket) {
8142 printf ("Error creating gridfs bucket: %s\n", error.message);
8143 return EXIT_FAILURE;
8144 }
8145
8146 /* 2. Insert a file. */
8147 file_stream = mongoc_stream_file_new_for_path (argv[1], O_RDONLY, 0);
8148 res = mongoc_gridfs_bucket_upload_from_stream (
8149 bucket, "my-file", file_stream, NULL, &file_id, &error);
8150 if (!res) {
8151 printf ("Error uploading file: %s\n", error.message);
8152 return EXIT_FAILURE;
8153 }
8154
8155 mongoc_stream_close (file_stream);
8156 mongoc_stream_destroy (file_stream);
8157
8158 /* 3. Download the file in GridFS to a local file. */
8159 file_stream = mongoc_stream_file_new_for_path (argv[2], O_CREAT | O_RDWR, 0);
8160 if (!file_stream) {
8161 perror ("Error opening file stream");
8162 return EXIT_FAILURE;
8163 }
8164
8165 res = mongoc_gridfs_bucket_download_to_stream (
8166 bucket, &file_id, file_stream, &error);
8167 if (!res) {
8168 printf ("Error downloading file to stream: %s\n", error.message);
8169 return EXIT_FAILURE;
8170 }
8171 mongoc_stream_close (file_stream);
8172 mongoc_stream_destroy (file_stream);
8173
8174 /* 4. List what files are available in GridFS. */
8175 bson_init (&filter);
8176 cursor = mongoc_gridfs_bucket_find (bucket, &filter, NULL);
8177
8178 while (mongoc_cursor_next (cursor, &doc)) {
8179 str = bson_as_canonical_extended_json (doc, NULL);
8180 printf ("%s\n", str);
8181 bson_free (str);
8182 }
8183
8184 /* 5. Delete the file that we added. */
8185 res = mongoc_gridfs_bucket_delete_by_id (bucket, &file_id, &error);
8186 if (!res) {
8187 printf ("Error deleting the file: %s\n", error.message);
8188 return EXIT_FAILURE;
8189 }
8190
8191 /* 6. Cleanup. */
8192 mongoc_stream_close (file_stream);
8193 mongoc_stream_destroy (file_stream);
8194 mongoc_cursor_destroy (cursor);
8195 bson_destroy (&filter);
8196 mongoc_gridfs_bucket_destroy (bucket);
8197 mongoc_database_destroy (db);
8198 mongoc_client_destroy (client);
8199 mongoc_cleanup ();
8200
8201 return EXIT_SUCCESS;
8202 }
8203
8204
8205 SEE ALSO:
8206 The MongoDB GridFS specification.
8207
8208 The non spec-compliant mongoc_gridfs_t.
8209
8210
8211 mongoc_gridfs_t
8212 WARNING:
8213 This GridFS implementation does not conform to the MongoDB GridFS
8214 specification. For a spec compliant implementation, use
8215 mongoc_gridfs_bucket_t.
8216
8217 Synopsis
8218 #include <mongoc/mongoc.h>
8219
8220 typedef struct _mongoc_gridfs_t mongoc_gridfs_t;
8221
8222 Description
8223 mongoc_gridfs_t provides a MongoDB gridfs implementation. The system as
8224 a whole is made up of gridfs objects, which contain gridfs_files and
8225 gridfs_file_lists. Essentially, a basic file system API.
8226
8227 There are extensive caveats about the kind of use cases gridfs is prac‐
8228 tical for. In particular, any writing after initial file creation is
8229 likely to both break any concurrent readers and be quite expensive.
8230 That said, this implementation does allow for arbitrary writes to ex‐
8231 isting gridfs object, just use them with caution.
8232
8233 mongoc_gridfs also integrates tightly with the mongoc_stream_t abstrac‐
8234 tion, which provides some convenient wrapping for file creation and
8235 reading/writing. It can be used without, but its worth looking to see
8236 if your problem can fit that model.
8237
8238 WARNING:
8239 mongoc_gridfs_t does not support read preferences. In a replica set,
8240 GridFS queries are always routed to the primary.
8241
8242 Thread Safety
8243 mongoc_gridfs_t is NOT thread-safe and should only be used in the same
8244 thread as the owning mongoc_client_t.
8245
8246 Lifecycle
8247 It is an error to free a mongoc_gridfs_t before freeing all related in‐
8248 stances of mongoc_gridfs_file_t and mongoc_gridfs_file_list_t.
8249
8250 Example
8251 example-gridfs.c
8252
8253 #include <assert.h>
8254 #include <mongoc/mongoc.h>
8255 #include <stdio.h>
8256 #include <stdlib.h>
8257 #include <fcntl.h>
8258
8259 int
8260 main (int argc, char *argv[])
8261 {
8262 mongoc_gridfs_t *gridfs;
8263 mongoc_gridfs_file_t *file;
8264 mongoc_gridfs_file_list_t *list;
8265 mongoc_gridfs_file_opt_t opt = {0};
8266 mongoc_client_t *client;
8267 const char *uri_string = "mongodb://127.0.0.1:27017/?appname=gridfs-example";
8268 mongoc_uri_t *uri;
8269 mongoc_stream_t *stream;
8270 bson_t filter;
8271 bson_t opts;
8272 bson_t child;
8273 bson_error_t error;
8274 ssize_t r;
8275 char buf[4096];
8276 mongoc_iovec_t iov;
8277 const char *filename;
8278 const char *command;
8279 bson_value_t id;
8280
8281 if (argc < 2) {
8282 fprintf (stderr, "usage - %s command ...\n", argv[0]);
8283 return EXIT_FAILURE;
8284 }
8285
8286 mongoc_init ();
8287
8288 iov.iov_base = (void *) buf;
8289 iov.iov_len = sizeof buf;
8290
8291 /* connect to localhost client */
8292 uri = mongoc_uri_new_with_error (uri_string, &error);
8293 if (!uri) {
8294 fprintf (stderr,
8295 "failed to parse URI: %s\n"
8296 "error message: %s\n",
8297 uri_string,
8298 error.message);
8299 return EXIT_FAILURE;
8300 }
8301
8302 client = mongoc_client_new_from_uri (uri);
8303 assert (client);
8304 mongoc_client_set_error_api (client, 2);
8305
8306 /* grab a gridfs handle in test prefixed by fs */
8307 gridfs = mongoc_client_get_gridfs (client, "test", "fs", &error);
8308 assert (gridfs);
8309
8310 command = argv[1];
8311 filename = argv[2];
8312
8313 if (strcmp (command, "read") == 0) {
8314 if (argc != 3) {
8315 fprintf (stderr, "usage - %s read filename\n", argv[0]);
8316 return EXIT_FAILURE;
8317 }
8318 file = mongoc_gridfs_find_one_by_filename (gridfs, filename, &error);
8319 assert (file);
8320
8321 stream = mongoc_stream_gridfs_new (file);
8322 assert (stream);
8323
8324 for (;;) {
8325 r = mongoc_stream_readv (stream, &iov, 1, -1, 0);
8326
8327 assert (r >= 0);
8328
8329 if (r == 0) {
8330 break;
8331 }
8332
8333 if (fwrite (iov.iov_base, 1, r, stdout) != r) {
8334 MONGOC_ERROR ("Failed to write to stdout. Exiting.\n");
8335 exit (1);
8336 }
8337 }
8338
8339 mongoc_stream_destroy (stream);
8340 mongoc_gridfs_file_destroy (file);
8341 } else if (strcmp (command, "list") == 0) {
8342 bson_init (&filter);
8343
8344 bson_init (&opts);
8345 bson_append_document_begin (&opts, "sort", -1, &child);
8346 BSON_APPEND_INT32 (&child, "filename", 1);
8347 bson_append_document_end (&opts, &child);
8348
8349 list = mongoc_gridfs_find_with_opts (gridfs, &filter, &opts);
8350
8351 bson_destroy (&filter);
8352 bson_destroy (&opts);
8353
8354 while ((file = mongoc_gridfs_file_list_next (list))) {
8355 const char *name = mongoc_gridfs_file_get_filename (file);
8356 printf ("%s\n", name ? name : "?");
8357
8358 mongoc_gridfs_file_destroy (file);
8359 }
8360
8361 mongoc_gridfs_file_list_destroy (list);
8362 } else if (strcmp (command, "write") == 0) {
8363 if (argc != 4) {
8364 fprintf (stderr, "usage - %s write filename input_file\n", argv[0]);
8365 return EXIT_FAILURE;
8366 }
8367
8368 stream = mongoc_stream_file_new_for_path (argv[3], O_RDONLY, 0);
8369 assert (stream);
8370
8371 opt.filename = filename;
8372
8373 /* the driver generates a file_id for you */
8374 file = mongoc_gridfs_create_file_from_stream (gridfs, stream, &opt);
8375 assert (file);
8376
8377 id.value_type = BSON_TYPE_INT32;
8378 id.value.v_int32 = 1;
8379
8380 /* optional: the following method specifies a file_id of any
8381 BSON type */
8382 if (!mongoc_gridfs_file_set_id (file, &id, &error)) {
8383 fprintf (stderr, "%s\n", error.message);
8384 return EXIT_FAILURE;
8385 }
8386
8387 if (!mongoc_gridfs_file_save (file)) {
8388 mongoc_gridfs_file_error (file, &error);
8389 fprintf (stderr, "Could not save: %s\n", error.message);
8390 return EXIT_FAILURE;
8391 }
8392
8393 mongoc_gridfs_file_destroy (file);
8394 } else {
8395 fprintf (stderr, "Unknown command");
8396 return EXIT_FAILURE;
8397 }
8398
8399 mongoc_gridfs_destroy (gridfs);
8400 mongoc_uri_destroy (uri);
8401 mongoc_client_destroy (client);
8402
8403 mongoc_cleanup ();
8404
8405 return EXIT_SUCCESS;
8406 }
8407
8408
8409 SEE ALSO:
8410 The MongoDB GridFS specification.
8411
8412 The spec-compliant mongoc_gridfs_bucket_t.
8413
8414
8415 mongoc_host_list_t
8416 Synopsis
8417 typedef struct {
8418 mongoc_host_list_t *next;
8419 char host[BSON_HOST_NAME_MAX + 1];
8420 char host_and_port[BSON_HOST_NAME_MAX + 7];
8421 uint16_t port;
8422 int family;
8423 void *padding[4];
8424 } mongoc_host_list_t;
8425
8426 Description
8427 The host and port of a MongoDB server. Can be part of a linked list:
8428 for example the return value of mongoc_uri_get_hosts() when multiple
8429 hosts are provided in the MongoDB URI.
8430
8431 SEE ALSO:
8432 mongoc_uri_get_hosts() and mongoc_cursor_get_host().
8433
8434
8435 mongoc_index_opt_geo_t
8436 Synopsis
8437 #include <mongoc/mongoc.h>
8438
8439 typedef struct {
8440 uint8_t twod_sphere_version;
8441 uint8_t twod_bits_precision;
8442 double twod_location_min;
8443 double twod_location_max;
8444 double haystack_bucket_size;
8445 uint8_t *padding[32];
8446 } mongoc_index_opt_geo_t;
8447
8448 Description
8449 This structure contains the options that may be used for tuning a GEO
8450 index.
8451
8452 SEE ALSO:
8453 mongoc_index_opt_t
8454
8455 mongoc_index_opt_wt_t
8456
8457
8458 mongoc_index_opt_t
8459 WARNING:
8460 Deprecated since version 1.8.0: This structure is deprecated and
8461 should not be used in new code. See Manage Collection Indexes.
8462
8463
8464 Synopsis
8465 #include <mongoc/mongoc.h>
8466
8467 typedef struct {
8468 bool is_initialized;
8469 bool background;
8470 bool unique;
8471 const char *name;
8472 bool drop_dups;
8473 bool sparse;
8474 int32_t expire_after_seconds;
8475 int32_t v;
8476 const bson_t *weights;
8477 const char *default_language;
8478 const char *language_override;
8479 mongoc_index_opt_geo_t *geo_options;
8480 mongoc_index_opt_storage_t *storage_options;
8481 const bson_t *partial_filter_expression;
8482 const bson_t *collation;
8483 void *padding[4];
8484 } mongoc_index_opt_t;
8485
8486 Description
8487 This structure contains the options that may be used for tuning a spe‐
8488 cific index.
8489
8490 See the createIndexes documentations in the MongoDB manual for descrip‐
8491 tions of individual options.
8492
8493 NOTE:
8494 dropDups is deprecated as of MongoDB version 3.0.0. This option is
8495 silently ignored by the server and unique index builds using this
8496 option will fail if a duplicate value is detected.
8497
8498 Example
8499 {
8500 bson_t keys;
8501 bson_error_t error;
8502 mongoc_index_opt_t opt;
8503 mongoc_index_opt_geo_t geo_opt;
8504
8505 mongoc_index_opt_init (&opt);
8506 mongoc_index_opt_geo_init (&geo_opt);
8507
8508 bson_init (&keys);
8509 BSON_APPEND_UTF8 (&keys, "location", "2d");
8510
8511 geo_opt.twod_location_min = -123;
8512 geo_opt.twod_location_max = +123;
8513 geo_opt.twod_bits_precision = 30;
8514 opt.geo_options = &geo_opt;
8515
8516 collection = mongoc_client_get_collection (client, "test", "geo_test");
8517 if (mongoc_collection_create_index (collection, &keys, &opt, &error)) {
8518 /* Successfully created the geo index */
8519 }
8520 bson_destroy (&keys);
8521 mongoc_collection_destroy (&collection);
8522 }
8523
8524 SEE ALSO:
8525 mongoc_index_opt_geo_t
8526
8527 mongoc_index_opt_wt_t
8528
8529
8530 mongoc_index_opt_wt_t
8531 Synopsis
8532 #include <mongoc/mongoc.h>
8533
8534 typedef struct {
8535 mongoc_index_opt_storage_t base;
8536 const char *config_str;
8537 void *padding[8];
8538 } mongoc_index_opt_wt_t;
8539
8540 Description
8541 This structure contains the options that may be used for tuning a
8542 WiredTiger specific index.
8543
8544 SEE ALSO:
8545 mongoc_index_opt_t
8546
8547 mongoc_index_opt_geo_t
8548
8549
8550 mongoc_insert_flags_t
8551 Flags for insert operations
8552
8553 Synopsis
8554 typedef enum {
8555 MONGOC_INSERT_NONE = 0,
8556 MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0,
8557 } mongoc_insert_flags_t;
8558
8559 #define MONGOC_INSERT_NO_VALIDATE (1U << 31)
8560
8561 Description
8562 These flags correspond to the MongoDB wire protocol. They may be bit‐
8563 wise or'd together. They may modify how an insert happens on the Mon‐
8564 goDB server.
8565
8566 Flag Values
8567 ┌──────────────────────────┬────────────────────────────┐
8568 │MONGOC_INSERT_NONE │ Specify no insert flags. │
8569 ├──────────────────────────┼────────────────────────────┤
8570 │MONGOC_INSERT_CON‐ │ Continue inserting docu‐ │
8571 │TINUE_ON_ERROR │ ments from the insertion │
8572 │ │ set even if one insert │
8573 │ │ fails. │
8574 └──────────────────────────┴────────────────────────────┘
8575
8576
8577
8578
8579
8580
8581 │MONGOC_INSERT_NO_VALIDATE │ Do not validate insertion │
8582 │ │ documents before perform‐ │
8583 │ │ ing an insert. Validation │
8584 │ │ can be expensive, so this │
8585 │ │ can save some time if you │
8586 │ │ know your documents are │
8587 │ │ already valid. │
8588 └──────────────────────────┴────────────────────────────┘
8589
8590 mongoc_iovec_t
8591 Synopsis
8592 Synopsis
8593 #include <mongoc/mongoc.h>
8594
8595 #ifdef _WIN32
8596 typedef struct {
8597 u_long iov_len;
8598 char *iov_base;
8599 } mongoc_iovec_t;
8600 #else
8601 typedef struct iovec mongoc_iovec_t;
8602 #endif
8603
8604 The mongoc_iovec_t structure is a portability abstraction for consumers
8605 of the mongoc_stream_t interfaces. It allows for scatter/gather I/O
8606 through the socket subsystem.
8607
8608 WARNING:
8609 When writing portable code, beware of the ordering of iov_len and
8610 iov_base as they are different on various platforms. Therefore, you
8611 should not use C initializers for initialization.
8612
8613 mongoc_optional_t
8614 A struct to store optional boolean values.
8615
8616 Synopsis
8617 Used to specify optional boolean flags, which may remain unset.
8618
8619 This is used within mongoc_server_api_t to track whether a flag was ex‐
8620 plicitly set.
8621
8622 mongoc_query_flags_t
8623 Flags for query operations
8624
8625 Synopsis
8626 typedef enum {
8627 MONGOC_QUERY_NONE = 0,
8628 MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1,
8629 MONGOC_QUERY_SECONDARY_OK = 1 << 2,
8630 MONGOC_QUERY_OPLOG_REPLAY = 1 << 3,
8631 MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4,
8632 MONGOC_QUERY_AWAIT_DATA = 1 << 5,
8633 MONGOC_QUERY_EXHAUST = 1 << 6,
8634 MONGOC_QUERY_PARTIAL = 1 << 7,
8635 } mongoc_query_flags_t;
8636
8637 Description
8638 These flags correspond to the MongoDB wire protocol. They may be bit‐
8639 wise or'd together. They may modify how a query is performed in the
8640 MongoDB server.
8641
8642 Flag Values
8643 ┌───────────────────────────┬────────────────────────────┐
8644 │MONGOC_QUERY_NONE │ Specify no query flags. │
8645 └───────────────────────────┴────────────────────────────┘
8646
8647
8648
8649
8650
8651 │MONGOC_QUERY_TAILABLE_CUR‐ │ Cursor will not be closed │
8652 │SOR │ when the last data is re‐ │
8653 │ │ trieved. You can resume │
8654 │ │ this cursor later. │
8655 ├───────────────────────────┼────────────────────────────┤
8656 │MONGOC_QUERY_SECONDARY_OK │ Allow query of replica set │
8657 │ │ secondaries. │
8658 ├───────────────────────────┼────────────────────────────┤
8659 │MONGOC_QUERY_OPLOG_REPLAY │ Used internally by Mon‐ │
8660 │ │ goDB. │
8661 ├───────────────────────────┼────────────────────────────┤
8662 │MONGOC_QUERY_NO_CUR‐ │ The server normally times │
8663 │SOR_TIMEOUT │ out an idle cursor after │
8664 │ │ an inactivity period (10 │
8665 │ │ minutes). This prevents │
8666 │ │ that. │
8667 ├───────────────────────────┼────────────────────────────┤
8668 │MONGOC_QUERY_AWAIT_DATA │ Use with MON‐ │
8669 │ │ GOC_QUERY_TAILABLE_CURSOR. │
8670 │ │ Block rather than return‐ │
8671 │ │ ing no data. After a pe‐ │
8672 │ │ riod, time out. │
8673 ├───────────────────────────┼────────────────────────────┤
8674 │MONGOC_QUERY_EXHAUST │ Stream the data down full │
8675 │ │ blast in multiple "reply" │
8676 │ │ packets. Faster when you │
8677 │ │ are pulling down a lot of │
8678 │ │ data and you know you want │
8679 │ │ to retrieve it all. Only │
8680 │ │ applies to cursors created │
8681 │ │ from a find operation │
8682 │ │ (i.e. │
8683 │ │ mongoc_collection_find()). │
8684 ├───────────────────────────┼────────────────────────────┤
8685 │MONGOC_QUERY_PARTIAL │ Get partial results from │
8686 │ │ mongos if some shards are │
8687 │ │ down (instead of throwing │
8688 │ │ an error). │
8689 └───────────────────────────┴────────────────────────────┘
8690
8691 mongoc_rand
8692 MongoDB Random Number Generator
8693
8694 Synopsis
8695 void
8696 mongoc_rand_add (const void *buf, int num, double entropy);
8697
8698 void
8699 mongoc_rand_seed (const void *buf, int num);
8700
8701 int
8702 mongoc_rand_status (void);
8703
8704 Description
8705 The mongoc_rand family of functions provide access to the low level
8706 randomness primitives used by the MongoDB C Driver. In particular,
8707 they control the creation of cryptographically strong pseudo-random
8708 bytes required by some security mechanisms.
8709
8710 While we can usually pull enough entropy from the environment, you may
8711 be required to seed the PRNG manually depending on your OS, hardware
8712 and other entropy consumers running on the same system.
8713
8714 Entropy
8715 mongoc_rand_add and mongoc_rand_seed allow the user to directly provide
8716 entropy. They differ insofar as mongoc_rand_seed requires that each
8717 bit provided is fully random. mongoc_rand_add allows the user to spec‐
8718 ify the degree of randomness in the provided bytes as well.
8719
8720 Status
8721 The mongoc_rand_status function allows the user to check the status of
8722 the mongoc PRNG. This can be used to guarantee sufficient entropy at
8723 program startup, rather than waiting for runtime errors to occur.
8724
8725 mongoc_read_concern_t
8726 Read Concern abstraction
8727
8728 Synopsis
8729 New in MongoDB 3.2.
8730
8731 The mongoc_read_concern_t allows clients to choose a level of isolation
8732 for their reads. The default, MONGOC_READ_CONCERN_LEVEL_LOCAL, is right
8733 for the great majority of applications.
8734
8735 You can specify a read concern on connection objects, database objects,
8736 or collection objects.
8737
8738 See readConcern on the MongoDB website for more information.
8739
8740 Read Concern is only sent to MongoDB when it has explicitly been set by
8741 mongoc_read_concern_set_level() to anything other than NULL.
8742
8743 Read Concern Levels
8744 ┌────────────────────┬─────────────────────┬─────────────────────┐
8745 │Macro │ Description │ First MongoDB ver‐ │
8746 │ │ │ sion │
8747 ├────────────────────┼─────────────────────┼─────────────────────┤
8748 │MONGOC_READ_CON‐ │ Level "local", the │ 3.2 │
8749 │CERN_LEVEL_LOCAL │ default. │ │
8750 ├────────────────────┼─────────────────────┼─────────────────────┤
8751 │MONGOC_READ_CON‐ │ Level "majority". │ 3.2 │
8752 │CERN_LEVEL_MAJORITY │ │ │
8753 ├────────────────────┼─────────────────────┼─────────────────────┤
8754 │MONGOC_READ_CON‐ │ Level "lineariz‐ │ 3.4 │
8755 │CERN_LEVEL_LIN‐ │ able". │ │
8756 │EARIZABLE │ │ │
8757 ├────────────────────┼─────────────────────┼─────────────────────┤
8758 │MONGOC_READ_CON‐ │ Level "available". │ 3.6 │
8759 │CERN_LEVEL_AVAIL‐ │ │ │
8760 │ABLE │ │ │
8761 ├────────────────────┼─────────────────────┼─────────────────────┤
8762 │MONGOC_READ_CON‐ │ Level "snapshot". │ 4.0 │
8763 │CERN_LEVEL_SNAPSHOT │ │ │
8764 └────────────────────┴─────────────────────┴─────────────────────┘
8765
8766 For the sake of compatibility with future versions of MongoDB,
8767 mongoc_read_concern_set_level() allows any string, not just this list
8768 of known read concern levels.
8769
8770 See Read Concern Levels in the MongoDB manual for more information
8771 about the individual read concern levels.
8772
8773 mongoc_read_mode_t
8774 Read Preference Modes
8775
8776 Synopsis
8777 typedef enum {
8778 MONGOC_READ_PRIMARY = (1 << 0),
8779 MONGOC_READ_SECONDARY = (1 << 1),
8780 MONGOC_READ_PRIMARY_PREFERRED = (1 << 2) | MONGOC_READ_PRIMARY,
8781 MONGOC_READ_SECONDARY_PREFERRED = (1 << 2) | MONGOC_READ_SECONDARY,
8782 MONGOC_READ_NEAREST = (1 << 3) | MONGOC_READ_SECONDARY,
8783 } mongoc_read_mode_t;
8784
8785 Description
8786 This enum describes how reads should be dispatched. The default is MON‐
8787 GOC_READ_PRIMARY.
8788
8789 Please see the MongoDB website for a description of Read Preferences.
8790
8791 mongoc_read_prefs_t
8792 A read preference abstraction
8793
8794 Synopsis
8795 mongoc_read_prefs_t provides an abstraction on top of the MongoDB con‐
8796 nection read preferences. It allows for hinting to the driver which
8797 nodes in a replica set should be accessed first and how.
8798
8799 You can specify a read preference mode on connection objects, database
8800 objects, collection objects, or per-operation. Generally, it makes the
8801 most sense to stick with the global default mode, MONGOC_READ_PRIMARY.
8802 All of the other modes come with caveats that won't be covered in great
8803 detail here.
8804
8805 Read Modes
8806 ┌───────────────────────────┬────────────────────────────┐
8807 │MONGOC_READ_PRIMARY │ Default mode. All opera‐ │
8808 │ │ tions read from the cur‐ │
8809 │ │ rent replica set primary. │
8810 ├───────────────────────────┼────────────────────────────┤
8811 │MONGOC_READ_SECONDARY │ All operations read from │
8812 │ │ among the nearest sec‐ │
8813 │ │ ondary members of the │
8814 │ │ replica set. │
8815 ├───────────────────────────┼────────────────────────────┤
8816 │MONGOC_READ_PRIMARY_PRE‐ │ In most situations, opera‐ │
8817 │FERRED │ tions read from the pri‐ │
8818 │ │ mary but if it is unavail‐ │
8819 │ │ able, operations read from │
8820 │ │ secondary members. │
8821 ├───────────────────────────┼────────────────────────────┤
8822 │MONGOC_READ_SECONDARY_PRE‐ │ In most situations, opera‐ │
8823 │FERRED │ tions read from among the │
8824 │ │ nearest secondary members, │
8825 │ │ but if no secondaries are │
8826 │ │ available, operations read │
8827 │ │ from the primary. │
8828 ├───────────────────────────┼────────────────────────────┤
8829 │MONGOC_READ_NEAREST │ Operations read from among │
8830 │ │ the nearest members of the │
8831 │ │ replica set, irrespective │
8832 │ │ of the member's type. │
8833 └───────────────────────────┴────────────────────────────┘
8834
8835 Tag Sets
8836 Tag sets allow you to specify custom read preferences and write con‐
8837 cerns so that your application can target operations to specific mem‐
8838 bers.
8839
8840 Custom read preferences and write concerns evaluate tags sets in dif‐
8841 ferent ways: read preferences consider the value of a tag when select‐
8842 ing a member to read from, while write concerns ignore the value of a
8843 tag when selecting a member, except to consider whether or not the
8844 value is unique.
8845
8846 You can specify tag sets with the following read preference modes:
8847
8848 • primaryPreferred
8849
8850 • secondary
8851
8852 • secondaryPreferred
8853
8854 • nearest
8855
8856 Tags are not compatible with MONGOC_READ_PRIMARY and, in general, only
8857 apply when selecting a secondary member of a set for a read operation.
8858 However, the nearest read mode, when combined with a tag set, will se‐
8859 lect the nearest member that matches the specified tag set, which may
8860 be a primary or secondary.
8861
8862 Tag sets are represented as a comma-separated list of colon-separated
8863 key-value pairs when provided as a connection string, e.g.
8864 dc:ny,rack:1.
8865
8866 To specify a list of tag sets, using multiple readPreferenceTags, e.g.
8867
8868 readPreferenceTags=dc:ny,rack:1;readPreferenceTags=dc:ny;readPreferenceTags=
8869
8870 Note the empty value for the last one, which means "match any secondary
8871 as a last resort".
8872
8873 Order matters when using multiple readPreferenceTags.
8874
8875 Tag Sets can also be configured using mongoc_read_prefs_set_tags().
8876
8877 All interfaces use the same member selection logic to choose the member
8878 to which to direct read operations, basing the choice on read prefer‐
8879 ence mode and tag sets.
8880
8881 Max Staleness
8882 When connected to replica set running MongoDB 3.4 or later, the driver
8883 estimates the staleness of each secondary based on lastWriteDate values
8884 provided in server hello responses.
8885
8886 Max Staleness is the maximum replication lag in seconds (wall clock
8887 time) that a secondary can suffer and still be eligible for reads. The
8888 default is MONGOC_NO_MAX_STALENESS, which disables staleness checks.
8889 Otherwise, it must be a positive integer at least MONGOC_SMALL‐
8890 EST_MAX_STALENESS_SECONDS (90 seconds).
8891
8892 Max Staleness is also supported by sharded clusters of replica sets if
8893 all servers run MongoDB 3.4 or later.
8894
8895 Hedged Reads
8896 When connecting to a sharded cluster running MongoDB 4.4 or later,
8897 reads can be sent in parallel to the two "best" hosts. Once one result
8898 returns, any other outstanding operations that were part of the hedged
8899 read are cancelled.
8900
8901 When the read preference mode is MONGOC_READ_NEAREST and the sharded
8902 cluster is running MongoDB 4.4 or later, hedged reads are enabled by
8903 default. Additionally, hedged reads may be explicitly enabled or dis‐
8904 abled by calling mongoc_read_prefs_set_hedge() with a BSON document,
8905 e.g.
8906
8907 {
8908 enabled: true
8909 }
8910
8911 Appropriate values for the enabled key are true or false.
8912
8913 mongoc_remove_flags_t
8914 Flags for deletion operations
8915
8916 Synopsis
8917 typedef enum {
8918 MONGOC_REMOVE_NONE = 0,
8919 MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0,
8920 } mongoc_remove_flags_t;
8921
8922 Description
8923 These flags correspond to the MongoDB wire protocol. They may be bit‐
8924 wise or'd together. They may change the number of documents that are
8925 removed during a remove command.
8926
8927 Flag Values
8928 ┌─────────────────────────┬────────────────────────────┐
8929 │MONGOC_REMOVE_NONE │ Specify no removal flags. │
8930 │ │ All matching documents │
8931 │ │ will be removed. │
8932 ├─────────────────────────┼────────────────────────────┤
8933 │MONGOC_REMOVE_SINGLE_RE‐ │ Only remove the first │
8934 │MOVE │ matching document from the │
8935 │ │ selector. │
8936 └─────────────────────────┴────────────────────────────┘
8937
8938 mongoc_reply_flags_t
8939 Flags from server replies
8940
8941 Synopsis
8942 typedef enum {
8943 MONGOC_REPLY_NONE = 0,
8944 MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0,
8945 MONGOC_REPLY_QUERY_FAILURE = 1 << 1,
8946 MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2,
8947 MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3,
8948 } mongoc_reply_flags_t;
8949
8950 Description
8951 These flags correspond to the wire protocol. They may be bitwise or'd
8952 together.
8953
8954 Flag Values
8955 ┌───────────────────────────┬────────────────────────────┐
8956 │MONGOC_REPLY_NONE │ No flags set. │
8957 ├───────────────────────────┼────────────────────────────┤
8958 │MONGOC_REPLY_CUR‐ │ No matching cursor was │
8959 │SOR_NOT_FOUND │ found on the server. │
8960 ├───────────────────────────┼────────────────────────────┤
8961 │MONGOC_REPLY_QUERY_FAILURE │ The query failed or was │
8962 │ │ invalid. Error document │
8963 │ │ has been provided. │
8964 ├───────────────────────────┼────────────────────────────┤
8965 │MONGOC_REPLY_SHARD_CON‐ │ Shard config is stale. │
8966 │FIG_STALE │ │
8967 ├───────────────────────────┼────────────────────────────┤
8968 │MONGOC_REPLY_AWAIT_CAPABLE │ If the returned cursor is │
8969 │ │ capable of MON‐ │
8970 │ │ GOC_QUERY_AWAIT_DATA. │
8971 └───────────────────────────┴────────────────────────────┘
8972
8973 mongoc_server_api_t
8974 A versioned API to use for connections.
8975
8976 Synopsis
8977 Used to specify which version of the MongoDB server's API to use for
8978 driver connections.
8979
8980 The server API type takes a mongoc_server_api_version_t. It can option‐
8981 ally be strict about the list of allowed commands in that API version,
8982 and can also optionally provide errors for deprecated commands in that
8983 API version.
8984
8985 A mongoc_server_api_t can be set on a client, and will then be sent to
8986 MongoDB for most commands run using that client.
8987
8988 mongoc_server_api_version_t
8989 A representation of server API version numbers.
8990
8991 Synopsis
8992 Used to specify which version of the MongoDB server's API to use for
8993 driver connections.
8994
8995 Supported API Versions
8996 The driver currently supports the following MongoDB API versions:
8997
8998 ┌─────────────────────┬────────────────────────┐
8999 │Enum value │ MongoDB version string │
9000 ├─────────────────────┼────────────────────────┤
9001 │MONGOC_SERVER_API_V1 │ "1" │
9002 └─────────────────────┴────────────────────────┘
9003
9004 mongoc_server_description_t
9005 Server description
9006
9007 Synopsis
9008 #include <mongoc/mongoc.h>
9009 typedef struct _mongoc_server_description_t mongoc_server_description_t
9010
9011 mongoc_server_description_t holds information about a mongod or mongos
9012 the driver is connected to.
9013
9014 Lifecycle
9015 Clean up a mongoc_server_description_t with
9016 mongoc_server_description_destroy() when necessary.
9017
9018 Applications receive a temporary reference to a mongoc_server_descrip‐
9019 tion_t as a parameter to an SDAM Monitoring callback that must not be
9020 destroyed. See Introduction to Application Performance Monitoring.
9021
9022 SEE ALSO:
9023 mongoc_client_get_server_descriptions().
9024
9025
9026 mongoc_session_opt_t
9027 #include <mongoc/mongoc.h>
9028
9029 typedef struct _mongoc_session_opt_t mongoc_session_opt_t;
9030
9031 Synopsis
9032 Start a session with mongoc_client_start_session(), use the session for
9033 a sequence of operations and multi-document transactions, then free it
9034 with mongoc_client_session_destroy(). Any mongoc_cursor_t or
9035 mongoc_change_stream_t using a session must be destroyed before the
9036 session, and a session must be destroyed before the mongoc_client_t it
9037 came from.
9038
9039 By default, sessions are causally consistent. To disable causal consis‐
9040 tency, before starting a session create a mongoc_session_opt_t with
9041 mongoc_session_opts_new() and call
9042 mongoc_session_opts_set_causal_consistency(), then free the struct with
9043 mongoc_session_opts_destroy().
9044
9045 Unacknowledged writes are prohibited with sessions.
9046
9047 A mongoc_client_session_t must be used by only one thread at a time.
9048 Due to session pooling, mongoc_client_start_session() may return a ses‐
9049 sion that has been idle for some time and is about to be closed after
9050 its idle timeout. Use the session within one minute of acquiring it to
9051 refresh the session and avoid a timeout.
9052
9053 See the example code for mongoc_session_opts_set_causal_consistency().
9054
9055 mongoc_socket_t
9056 Portable socket abstraction
9057
9058 Synopsis
9059 #include <mongoc/mongoc.h>
9060
9061 typedef struct _mongoc_socket_t mongoc_socket_t
9062
9063 Synopsis
9064 This structure provides a socket abstraction that is friendlier for
9065 portability than BSD sockets directly. Inconsistencies between Linux,
9066 various BSDs, Solaris, and Windows are handled here.
9067
9068 mongoc_ssl_opt_t
9069 Synopsis
9070 typedef struct {
9071 const char *pem_file;
9072 const char *pem_pwd;
9073 const char *ca_file;
9074 const char *ca_dir;
9075 const char *crl_file;
9076 bool weak_cert_validation;
9077 bool allow_invalid_hostname;
9078 void *internal;
9079 void *padding[6];
9080 } mongoc_ssl_opt_t;
9081
9082 Description
9083 This structure is used to set the TLS options for a mongoc_client_t or
9084 mongoc_client_pool_t.
9085
9086 Beginning in version 1.2.0, once a pool or client has any TLS options
9087 set, all connections use TLS, even if ssl=true is omitted from the Mon‐
9088 goDB URI. Before, TLS options were ignored unless tls=true was included
9089 in the URI.
9090
9091 As of 1.4.0, the mongoc_client_pool_set_ssl_opts() and
9092 mongoc_client_set_ssl_opts() will not only shallow copy the struct, but
9093 will also copy the const char*. It is therefore no longer needed to
9094 make sure the values remain valid after setting them.
9095
9096 SEE ALSO:
9097 Configuring TLS
9098
9099 mongoc_client_set_ssl_opts()
9100
9101 mongoc_client_pool_set_ssl_opts()
9102
9103
9104 mongoc_stream_buffered_t
9105 Synopsis
9106 typedef struct _mongoc_stream_buffered_t mongoc_stream_buffered_t;
9107
9108 Description
9109 mongoc_stream_buffered_t should be considered a subclass of
9110 mongoc_stream_t. It performs buffering on an underlying stream.
9111
9112 SEE ALSO:
9113 mongoc_stream_buffered_new()
9114
9115 mongoc_stream_destroy()
9116
9117
9118 mongoc_stream_file_t
9119 Synopsis
9120 typedef struct _mongoc_stream_file_t mongoc_stream_file_t
9121
9122 mongoc_stream_file_t is a mongoc_stream_t subclass for working with
9123 standard UNIX style file-descriptors.
9124
9125 mongoc_stream_socket_t
9126 Synopsis
9127 typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t
9128
9129 mongoc_stream_socket_t should be considered a subclass of
9130 mongoc_stream_t that works upon socket streams.
9131
9132 mongoc_stream_t
9133 Synopsis
9134 typedef struct _mongoc_stream_t mongoc_stream_t
9135
9136 mongoc_stream_t provides a generic streaming IO abstraction based on a
9137 struct of pointers interface. The idea is to allow wrappers, perhaps
9138 other language drivers, to easily shim their IO system on top of mon‐
9139 goc_stream_t.
9140
9141 The API for the stream abstraction is currently private and non-exten‐
9142 sible.
9143
9144 Stream Types
9145 There are a number of built in stream types that come with mongoc. The
9146 default configuration is a buffered unix stream. If TLS is in use, that
9147 in turn is wrapped in a tls stream.
9148
9149 SEE ALSO:
9150 mongoc_stream_buffered_t
9151
9152 mongoc_stream_file_t
9153
9154 mongoc_stream_socket_t
9155
9156 mongoc_stream_tls_t
9157
9158
9159 mongoc_stream_tls_t
9160 Synopsis
9161 typedef struct _mongoc_stream_tls_t mongoc_stream_tls_t
9162
9163 mongoc_stream_tls_t is a mongoc_stream_t subclass for working with TLS
9164 streams.
9165
9166 mongoc_topology_description_t
9167 Status of MongoDB Servers
9168
9169 Synopsis
9170 typedef struct _mongoc_topology_description_t mongoc_topology_description_t;
9171
9172 mongoc_topology_description_t is an opaque type representing the
9173 driver's knowledge of the MongoDB server or servers it is connected to.
9174 Its API conforms to the SDAM Monitoring Specification.
9175
9176 Applications receive a temporary reference to a mongoc_topology_de‐
9177 scription_t as a parameter to an SDAM Monitoring callback that must not
9178 be destroyed. See Introduction to Application Performance Monitoring.
9179
9180 mongoc_transaction_opt_t
9181 #include <mongoc/mongoc.h>
9182
9183 typedef struct _mongoc_transaction_opt_t mongoc_transaction_opt_t;
9184
9185 Synopsis
9186 Options for starting a multi-document transaction.
9187
9188 When a session is first created with mongoc_client_start_session(), it
9189 inherits from the client the read concern, write concern, and read
9190 preference with which to start transactions. Each of these fields can
9191 be overridden independently. Create a mongoc_transaction_opt_t with
9192 mongoc_transaction_opts_new(), and pass a non-NULL option to any of the
9193 mongoc_transaction_opt_t setter functions:
9194
9195 • mongoc_transaction_opts_set_read_concern()
9196
9197 • mongoc_transaction_opts_set_write_concern()
9198
9199 • mongoc_transaction_opts_set_read_prefs()
9200
9201 Pass the resulting transaction options to
9202 mongoc_client_session_start_transaction(). Each field set in the trans‐
9203 action options overrides the inherited client configuration.
9204
9205 Example
9206 example-transaction.c
9207
9208 /* gcc example-transaction.c -o example-transaction \
9209 * $(pkg-config --cflags --libs libmongoc-1.0) */
9210
9211 /* ./example-transaction [CONNECTION_STRING] */
9212
9213 #include <stdio.h>
9214 #include <mongoc/mongoc.h>
9215
9216
9217 int
9218 main (int argc, char *argv[])
9219 {
9220 int exit_code = EXIT_FAILURE;
9221
9222 mongoc_client_t *client = NULL;
9223 mongoc_database_t *database = NULL;
9224 mongoc_collection_t *collection = NULL;
9225 mongoc_client_session_t *session = NULL;
9226 mongoc_session_opt_t *session_opts = NULL;
9227 mongoc_transaction_opt_t *default_txn_opts = NULL;
9228 mongoc_transaction_opt_t *txn_opts = NULL;
9229 mongoc_read_concern_t *read_concern = NULL;
9230 mongoc_write_concern_t *write_concern = NULL;
9231 const char *uri_string = "mongodb://127.0.0.1/?appname=transaction-example";
9232 mongoc_uri_t *uri;
9233 bson_error_t error;
9234 bson_t *doc = NULL;
9235 bson_t *insert_opts = NULL;
9236 int32_t i;
9237 int64_t start;
9238 bson_t reply = BSON_INITIALIZER;
9239 char *reply_json;
9240 bool r;
9241
9242 mongoc_init ();
9243
9244 if (argc > 1) {
9245 uri_string = argv[1];
9246 }
9247
9248 uri = mongoc_uri_new_with_error (uri_string, &error);
9249 if (!uri) {
9250 MONGOC_ERROR ("failed to parse URI: %s\n"
9251 "error message: %s\n",
9252 uri_string,
9253 error.message);
9254 goto done;
9255 }
9256
9257 client = mongoc_client_new_from_uri (uri);
9258 if (!client) {
9259 goto done;
9260 }
9261
9262 mongoc_client_set_error_api (client, 2);
9263 database = mongoc_client_get_database (client, "example-transaction");
9264
9265 /* inserting into a nonexistent collection normally creates it, but a
9266 * collection can't be created in a transaction; create it now */
9267 collection =
9268 mongoc_database_create_collection (database, "collection", NULL, &error);
9269
9270 if (!collection) {
9271 /* code 48 is NamespaceExists, see error_codes.err in mongodb source */
9272 if (error.code == 48) {
9273 collection = mongoc_database_get_collection (database, "collection");
9274 } else {
9275 MONGOC_ERROR ("Failed to create collection: %s", error.message);
9276 goto done;
9277 }
9278 }
9279
9280 /* a transaction's read preferences, read concern, and write concern can be
9281 * set on the client, on the default transaction options, or when starting
9282 * the transaction. for the sake of this example, set read concern on the
9283 * default transaction options. */
9284 default_txn_opts = mongoc_transaction_opts_new ();
9285 read_concern = mongoc_read_concern_new ();
9286 mongoc_read_concern_set_level (read_concern, "snapshot");
9287 mongoc_transaction_opts_set_read_concern (default_txn_opts, read_concern);
9288 session_opts = mongoc_session_opts_new ();
9289 mongoc_session_opts_set_default_transaction_opts (session_opts,
9290 default_txn_opts);
9291
9292 session = mongoc_client_start_session (client, session_opts, &error);
9293 if (!session) {
9294 MONGOC_ERROR ("Failed to start session: %s", error.message);
9295 goto done;
9296 }
9297
9298 /* in this example, set write concern when starting the transaction */
9299 txn_opts = mongoc_transaction_opts_new ();
9300 write_concern = mongoc_write_concern_new ();
9301 mongoc_write_concern_set_wmajority (write_concern, 1000 /* wtimeout */);
9302 mongoc_transaction_opts_set_write_concern (txn_opts, write_concern);
9303
9304 insert_opts = bson_new ();
9305 if (!mongoc_client_session_append (session, insert_opts, &error)) {
9306 MONGOC_ERROR ("Could not add session to opts: %s", error.message);
9307 goto done;
9308 }
9309
9310 retry_transaction:
9311 r = mongoc_client_session_start_transaction (session, txn_opts, &error);
9312 if (!r) {
9313 MONGOC_ERROR ("Failed to start transaction: %s", error.message);
9314 goto done;
9315 }
9316
9317 /* insert two documents - on error, retry the whole transaction */
9318 for (i = 0; i < 2; i++) {
9319 doc = BCON_NEW ("_id", BCON_INT32 (i));
9320 bson_destroy (&reply);
9321 r = mongoc_collection_insert_one (
9322 collection, doc, insert_opts, &reply, &error);
9323
9324 bson_destroy (doc);
9325
9326 if (!r) {
9327 MONGOC_ERROR ("Insert failed: %s", error.message);
9328 mongoc_client_session_abort_transaction (session, NULL);
9329
9330 /* a network error, primary failover, or other temporary error in a
9331 * transaction includes {"errorLabels": ["TransientTransactionError"]},
9332 * meaning that trying the entire transaction again may succeed
9333 */
9334 if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
9335 goto retry_transaction;
9336 }
9337
9338 goto done;
9339 }
9340
9341 reply_json = bson_as_json (&reply, NULL);
9342 printf ("%s\n", reply_json);
9343 bson_free (reply_json);
9344 }
9345
9346 /* in case of transient errors, retry for 5 seconds to commit transaction */
9347 start = bson_get_monotonic_time ();
9348 while (bson_get_monotonic_time () - start < 5 * 1000 * 1000) {
9349 bson_destroy (&reply);
9350 r = mongoc_client_session_commit_transaction (session, &reply, &error);
9351 if (r) {
9352 /* success */
9353 break;
9354 } else {
9355 MONGOC_ERROR ("Warning: commit failed: %s", error.message);
9356 if (mongoc_error_has_label (&reply, "TransientTransactionError")) {
9357 goto retry_transaction;
9358 } else if (mongoc_error_has_label (&reply,
9359 "UnknownTransactionCommitResult")) {
9360 /* try again to commit */
9361 continue;
9362 }
9363
9364 /* unrecoverable error trying to commit */
9365 break;
9366 }
9367 }
9368
9369 exit_code = EXIT_SUCCESS;
9370
9371 done:
9372 bson_destroy (&reply);
9373 bson_destroy (insert_opts);
9374 mongoc_write_concern_destroy (write_concern);
9375 mongoc_read_concern_destroy (read_concern);
9376 mongoc_transaction_opts_destroy (txn_opts);
9377 mongoc_transaction_opts_destroy (default_txn_opts);
9378 mongoc_client_session_destroy (session);
9379 mongoc_collection_destroy (collection);
9380 mongoc_database_destroy (database);
9381 mongoc_uri_destroy (uri);
9382 mongoc_client_destroy (client);
9383
9384 mongoc_cleanup ();
9385
9386 return exit_code;
9387 }
9388
9389
9390 mongoc_transaction_state_t
9391 Constants for transaction states
9392
9393 Synopsis
9394 typedef enum {
9395 MONGOC_TRANSACTION_NONE = 0,
9396 MONGOC_TRANSACTION_STARTING = 1,
9397 MONGOC_TRANSACTION_IN_PROGRESS = 2,
9398 MONGOC_TRANSACTION_COMMITTED = 3,
9399 MONGOC_TRANSACTION_ABORTED = 4,
9400 } mongoc_transaction_state_t;
9401
9402 Description
9403 These constants describe the current transaction state of a session.
9404
9405 Flag Values
9406 ┌───────────────────────────┬────────────────────────────┐
9407 │MONGOC_TRANSACTION_NONE │ There is no transaction in │
9408 │ │ progress. │
9409 ├───────────────────────────┼────────────────────────────┤
9410 │MONGOC_TRANSACTION_START‐ │ A transaction has been │
9411 │ING │ started, but no operation │
9412 │ │ has been sent to the │
9413 │ │ server. │
9414 ├───────────────────────────┼────────────────────────────┤
9415 │MONGOC_TRANSAC‐ │ A transaction is in │
9416 │TION_IN_PROGRESS │ progress. │
9417 ├───────────────────────────┼────────────────────────────┤
9418 │MONGOC_TRANSACTION_COMMIT‐ │ The transaction was com‐ │
9419 │TED │ mitted. │
9420 ├───────────────────────────┼────────────────────────────┤
9421 │MONGOC_TRANSACTION_ABORTED │ The transaction was │
9422 │ │ aborted. │
9423 └───────────────────────────┴────────────────────────────┘
9424
9425 mongoc_update_flags_t
9426 Flags for update operations
9427
9428 Synopsis
9429 typedef enum {
9430 MONGOC_UPDATE_NONE = 0,
9431 MONGOC_UPDATE_UPSERT = 1 << 0,
9432 MONGOC_UPDATE_MULTI_UPDATE = 1 << 1,
9433 } mongoc_update_flags_t;
9434
9435 #define MONGOC_UPDATE_NO_VALIDATE (1U << 31)
9436
9437 Description
9438 These flags correspond to the MongoDB wire protocol. They may be bit‐
9439 wise or'd together. The allow for modifying the way an update is per‐
9440 formed in the MongoDB server.
9441
9442 Flag Values
9443 ┌───────────────────────────┬────────────────────────────┐
9444 │MONGOC_UPDATE_NONE │ No update flags set. │
9445 ├───────────────────────────┼────────────────────────────┤
9446 │MONGOC_UPDATE_UPSERT │ If an upsert should be │
9447 │ │ performed. │
9448 ├───────────────────────────┼────────────────────────────┤
9449 │MONGOC_UPDATE_MULTI_UPDATE │ If more than a single │
9450 │ │ matching document should │
9451 │ │ be updated. By default │
9452 │ │ only the first document is │
9453 │ │ updated. │
9454 ├───────────────────────────┼────────────────────────────┤
9455 │MONGOC_UPDATE_NO_VALIDATE │ Do not perform client side │
9456 │ │ BSON validations when per‐ │
9457 │ │ forming an update. This is │
9458 │ │ useful if you already know │
9459 │ │ your BSON documents are │
9460 │ │ valid. │
9461 └───────────────────────────┴────────────────────────────┘
9462
9463 mongoc_uri_t
9464 Synopsis
9465 typedef struct _mongoc_uri_t mongoc_uri_t;
9466
9467 Description
9468 mongoc_uri_t provides an abstraction on top of the MongoDB connection
9469 URI format. It provides standardized parsing as well as convenience
9470 methods for extracting useful information such as replica hosts or au‐
9471 thorization information.
9472
9473 See Connection String URI Reference on the MongoDB website for more in‐
9474 formation.
9475
9476 Format
9477 mongodb[+srv]:// <1>
9478 [username:password@] <2>
9479 host1 <3>
9480 [:port1] <4>
9481 [,host2[:port2],...[,hostN[:portN]]] <5>
9482 [/[database] <6>
9483 [?options]] <7>
9484
9485 1. "mongodb" is the specifier of the MongoDB protocol. Use "mon‐
9486 godb+srv" with a single service name in place of "host1" to specify
9487 the initial list of servers with an SRV record.
9488
9489 2. An optional username and password.
9490
9491 3. The only required part of the uri. This specifies either a host‐
9492 name, IPv4 address, IPv6 address enclosed in "[" and "]", or UNIX
9493 domain socket.
9494
9495 4. An optional port number. Defaults to :27017.
9496
9497 5. Extra optional hosts and ports. You would specify multiple hosts,
9498 for example, for connections to replica sets.
9499
9500 6. The name of the database to authenticate if the connection string
9501 includes authentication credentials. If /database is not specified
9502 and the connection string includes credentials, defaults to the 'ad‐
9503 min' database.
9504
9505 7. Connection specific options.
9506
9507 NOTE:
9508 Option names are case-insensitive. Do not repeat the same option
9509 (e.g. "mongodb://localhost/db?opt=value1&OPT=value2") since this may
9510 have unexpected results.
9511
9512 The MongoDB C Driver exposes constants for each supported connection
9513 option. These constants make it easier to discover connection options,
9514 but their string values can be used as well.
9515
9516 For example, the following calls are equal.
9517
9518 uri = mongoc_uri_new ("mongodb://localhost/?" MONGOC_URI_APPNAME "=applicationName");
9519 uri = mongoc_uri_new ("mongodb://localhost/?appname=applicationName");
9520 uri = mongoc_uri_new ("mongodb://localhost/?appName=applicationName");
9521
9522 Replica Set Example
9523 To describe a connection to a replica set named 'test' with the follow‐
9524 ing mongod hosts:
9525
9526 • db1.example.com on port 27017
9527
9528 • db2.example.com on port 2500
9529
9530 You would use a connection string that resembles the following.
9531
9532 mongodb://db1.example.com,db2.example.com:2500/?replicaSet=test
9533
9534 SRV Example
9535 If you have configured an SRV record with a name like "_mon‐
9536 godb._tcp.server.example.com" whose records are a list of one or more
9537 MongoDB server hostnames, use a connection string like this:
9538
9539 uri = mongoc_uri_new ("mongodb+srv://server.example.com/?replicaSet=rs&appName=applicationName");
9540
9541 The driver prefixes the service name with "_mongodb._tcp.", then per‐
9542 forms a DNS SRV query to resolve the service name to one or more host‐
9543 names. If this query succeeds, the driver performs a DNS TXT query on
9544 the service name (without the "_mongodb._tcp" prefix) for additional
9545 URI options configured as TXT records.
9546
9547 On Unix, the MongoDB C Driver relies on libresolv to look up SRV and
9548 TXT records. If libresolv is unavailable, then using a "mongodb+srv"
9549 URI will cause an error. If your libresolv lacks res_nsearch then the
9550 driver will fall back to res_search, which is not thread-safe.
9551
9552 IPv4 and IPv6
9553 If connecting to a hostname that has both IPv4 and IPv6 DNS records,
9554 the behavior follows RFC-6555. A connection to the IPv6 address is at‐
9555 tempted first. If IPv6 fails, then a connection is attempted to the
9556 IPv4 address. If the connection attempt to IPv6 does not complete
9557 within 250ms, then IPv4 is tried in parallel. Whichever succeeds con‐
9558 nection first cancels the other. The successful DNS result is cached
9559 for 10 minutes.
9560
9561 As a consequence, attempts to connect to a mongod only listening on
9562 IPv4 may be delayed if there are both A (IPv4) and AAAA (IPv6) DNS
9563 records associated with the host.
9564
9565 To avoid a delay, configure hostnames to match the MongoDB configura‐
9566 tion. That is, only create an A record if the mongod is only listening
9567 on IPv4.
9568
9569 Connection Options
9570┌───────────────────┬──────────────────┬──────────────────┬─────────────────────────────────────┐
9571│Constant │ Key │ Default │ Description │
9572├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9573│MON‐ │ retryreads │ true │ If "true" and │
9574│GOC_URI_RETRYREADS │ │ │ the server is a │
9575│ │ │ │ MongoDB 3.6+ │
9576│ │ │ │ standalone, │
9577│ │ │ │ replica set, or │
9578│ │ │ │ sharded cluster, │
9579│ │ │ │ the driver │
9580│ │ │ │ safely retries a │
9581│ │ │ │ read that failed │
9582│ │ │ │ due to a network │
9583│ │ │ │ error or replica │
9584│ │ │ │ set failover. │
9585├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9586│MONGOC_URI_RETRY‐ │ retrywrites │ true if driver │ If "true" and │
9587│WRITES │ │ built w/ TLS │ the server is a │
9588│ │ │ │ MongoDB 3.6+ │
9589│ │ │ │ replica set or │
9590│ │ │ │ sharded cluster, │
9591│ │ │ │ the driver │
9592│ │ │ │ safely retries a │
9593│ │ │ │ write that │
9594│ │ │ │ failed due to a │
9595│ │ │ │ network error or │
9596│ │ │ │ replica set │
9597│ │ │ │ failover. Only │
9598│ │ │ │ inserts, updates │
9599│ │ │ │ of single docu‐ │
9600│ │ │ │ ments, or │
9601│ │ │ │ deletes of sin‐ │
9602│ │ │ │ gle documents │
9603│ │ │ │ are retried. │
9604├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9605│MONGOC_URI_APPNAME │ appname │ Empty (no app‐ │ The client ap‐ │
9606│ │ │ name) │ plication name. │
9607│ │ │ │ This value is │
9608│ │ │ │ used by MongoDB │
9609│ │ │ │ when it logs │
9610│ │ │ │ connection in‐ │
9611│ │ │ │ formation and │
9612│ │ │ │ profile informa‐ │
9613│ │ │ │ tion, such as │
9614│ │ │ │ slow queries. │
9615├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9616│MONGOC_URI_TLS │ tls │ Empty (not set, │ {true|false}, │
9617│ │ │ same as false) │ indicating if │
9618│ │ │ │ TLS must be │
9619│ │ │ │ used. (See also │
9620│ │ │ │ mongoc_client_set_ssl_opts() │
9621│ │ │ │ and │
9622│ │ │ │ mongoc_client_pool_set_ssl_opts().) │
9623└───────────────────┴──────────────────┴──────────────────┴─────────────────────────────────────┘
9624
9625│MONGOC_URI_COM‐ │ compressors │ Empty (no com‐ │ Comma separated list of compres‐ │
9626│PRESSORS │ │ pressors) │ sors, if any, to use to compress │
9627│ │ │ │ the wire protocol messages. Snappy, │
9628│ │ │ │ zlib, and zstd are optional build │
9629│ │ │ │ time dependencies, and enable the │
9630│ │ │ │ "snappy", "zlib", and "zstd" values │
9631│ │ │ │ respectively. │
9632├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9633│MONGOC_URI_CON‐ │ connecttimeoutms │ 10,000 ms (10 │ This setting applies to new server │
9634│NECTTIMEOUTMS │ │ seconds) │ connections. It is also used as the │
9635│ │ │ │ socket timeout for server discovery │
9636│ │ │ │ and monitoring operations. │
9637├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9638│MONGOC_URI_SOCKET‐ │ sockettimeoutms │ 300,000 ms (5 │ The time in milliseconds to attempt │
9639│TIMEOUTMS │ │ minutes) │ to send or receive on a socket be‐ │
9640│ │ │ │ fore the attempt times out. │
9641├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9642│MONGOC_URI_REPLI‐ │ replicaset │ Empty (no repli‐ │ The name of the Replica Set that │
9643│CASET │ │ caset) │ the driver should connect to. │
9644├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9645│MONGOC_URI_ZLIB‐ │ zlibcompression‐ │ -1 │ When the MONGOC_URI_COMPRESSORS in‐ │
9646│COMPRESSIONLEVEL │ level │ │ cludes "zlib" this options config‐ │
9647│ │ │ │ ures the zlib compression level, │
9648│ │ │ │ when the zlib compressor is used to │
9649│ │ │ │ compress client data. │
9650├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9651│MONGOC_URI_LOAD‐ │ loadbalanced │ false │ If true, this indicates the driver │
9652│BALANCED │ │ │ is connecting to a MongoDB cluster │
9653│ │ │ │ behind a load balancer. │
9654├───────────────────┼──────────────────┼──────────────────┼─────────────────────────────────────┤
9655│MONGOC_URI_SRVMAX‐ │ srvmaxhosts │ 0 │ If zero, the number of hosts in DNS │
9656│HOSTS │ │ │ results is unlimited. If greater │
9657│ │ │ │ than zero, the number of hosts in │
9658│ │ │ │ DNS results is limited to being │
9659│ │ │ │ less than or equal to the given │
9660│ │ │ │ value. │
9661└───────────────────┴──────────────────┴──────────────────┴─────────────────────────────────────┘
9662
9663 Setting any of the *timeoutMS options above to 0 will be interpreted as
9664 "use the default value".
9665
9666 Authentication Options
9667 ┌────────────────────┬────────────────────┬─────────────────────┐
9668 │Constant │ Key │ Description │
9669 ├────────────────────┼────────────────────┼─────────────────────┤
9670 │MONGOC_URI_AUTH‐ │ authmechanism │ Specifies the mech‐ │
9671 │MECHANISM │ │ anism to use when │
9672 │ │ │ authenticating as │
9673 │ │ │ the provided user. │
9674 │ │ │ See Authentication │
9675 │ │ │ for supported val‐ │
9676 │ │ │ ues. │
9677 ├────────────────────┼────────────────────┼─────────────────────┤
9678 │MONGOC_URI_AUTH‐ │ authmechanismprop‐ │ Certain authentica‐ │
9679 │MECHANISMPROPERTIES │ erties │ tion mechanisms │
9680 │ │ │ have additional op‐ │
9681 │ │ │ tions that can be │
9682 │ │ │ configured. These │
9683 │ │ │ options should be │
9684 │ │ │ provided as comma │
9685 │ │ │ separated op‐ │
9686 │ │ │ tion_key:op‐ │
9687 │ │ │ tion_value pair and │
9688 │ │ │ provided as auth‐ │
9689 │ │ │ MechanismProper‐ │
9690 │ │ │ ties. Specifying │
9691 │ │ │ the same option_key │
9692 │ │ │ multiple times has │
9693 │ │ │ undefined behavior. │
9694 └────────────────────┴────────────────────┴─────────────────────┘
9695
9696
9697
9698
9699
9700
9701 │MONGOC_URI_AUTH‐ │ authsource │ The authSource de‐ │
9702 │SOURCE │ │ fines the database │
9703 │ │ │ that should be used │
9704 │ │ │ to authenticate to. │
9705 │ │ │ It is unnecessary │
9706 │ │ │ to provide this op‐ │
9707 │ │ │ tion the database │
9708 │ │ │ name is the same as │
9709 │ │ │ the database used │
9710 │ │ │ in the URI. │
9711 └────────────────────┴────────────────────┴─────────────────────┘
9712
9713 Mechanism Properties
9714 ┌────────────────────┬───────────────────┬─────────────────────┐
9715 │Constant │ Key │ Description │
9716 ├────────────────────┼───────────────────┼─────────────────────┤
9717 │MONGOC_URI_CANONI‐ │ canonicalizehost‐ │ Use the canonical │
9718 │CALIZEHOSTNAME │ name │ hostname of the │
9719 │ │ │ service, rather │
9720 │ │ │ than its configured │
9721 │ │ │ alias, when authen‐ │
9722 │ │ │ ticating with │
9723 │ │ │ Cyrus-SASL Ker‐ │
9724 │ │ │ beros. │
9725 ├────────────────────┼───────────────────┼─────────────────────┤
9726 │MONGOC_URI_GSSAPIS‐ │ gssapiservicename │ Use alternative │
9727 │ERVICENAME │ │ service name. The │
9728 │ │ │ default is mongodb. │
9729 └────────────────────┴───────────────────┴─────────────────────┘
9730
9731 TLS Options
9732 ┌────────────────────┬─────────────────────┬─────────────────────┐
9733 │Constant │ Key │ Description │
9734 ├────────────────────┼─────────────────────┼─────────────────────┤
9735 │MONGOC_URI_TLS │ tls │ {true|false}, indi‐ │
9736 │ │ │ cating if TLS must │
9737 │ │ │ be used. │
9738 ├────────────────────┼─────────────────────┼─────────────────────┤
9739 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ Path to PEM format‐ │
9740 │TIFICATEKEYFILE │ file │ ted Private Key, │
9741 │ │ │ with its Public │
9742 │ │ │ Certificate con‐ │
9743 │ │ │ catenated at the │
9744 │ │ │ end. │
9745 ├────────────────────┼─────────────────────┼─────────────────────┤
9746 │MONGOC_URI_TLSCER‐ │ tlscertificatekey‐ │ The password, if │
9747 │TIFICATEKEY‐ │ password │ any, to use to un‐ │
9748 │FILEPASSWORD │ │ lock encrypted Pri‐ │
9749 │ │ │ vate Key. │
9750 ├────────────────────┼─────────────────────┼─────────────────────┤
9751 │MON‐ │ tlscafile │ One, or a bundle │
9752 │GOC_URI_TLSCAFILE │ │ of, Certificate Au‐ │
9753 │ │ │ thorities whom │
9754 │ │ │ should be consid‐ │
9755 │ │ │ ered to be trusted. │
9756 ├────────────────────┼─────────────────────┼─────────────────────┤
9757 │MONGOC_URI_TLSAL‐ │ tlsallowinvalidcer‐ │ Accept and ignore │
9758 │LOWINVALIDCERTIFI‐ │ tificates │ certificate verifi‐ │
9759 │CATES │ │ cation errors (e.g. │
9760 │ │ │ untrusted issuer, │
9761 │ │ │ expired, etc.) │
9762 ├────────────────────┼─────────────────────┼─────────────────────┤
9763 │MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │ Ignore hostname │
9764 │LOWINVALIDHOSTNAMES │ hostnames │ verification of the │
9765 │ │ │ certificate (e.g. │
9766 │ │ │ Man In The Middle, │
9767 │ │ │ using valid cer‐ │
9768 │ │ │ tificate, but is‐ │
9769 │ │ │ sued for another │
9770 │ │ │ hostname) │
9771 └────────────────────┴─────────────────────┴─────────────────────┘
9772
9773
9774
9775
9776
9777 │MONGOC_URI_TLSINSE‐ │ tlsinsecure │ {true|false}, indi‐ │
9778 │CURE │ │ cating if insecure │
9779 │ │ │ TLS options should │
9780 │ │ │ be used. Currently │
9781 │ │ │ this implies MON‐ │
9782 │ │ │ GOC_URI_TLSALLOWIN‐ │
9783 │ │ │ VALIDCERTIFICATES │
9784 │ │ │ and MONGOC_URI_TL‐ │
9785 │ │ │ SALLOWINVALIDHOST‐ │
9786 │ │ │ NAMES. │
9787 ├────────────────────┼─────────────────────┼─────────────────────┤
9788 │MONGOC_URI_TLSDIS‐ │ tlsdisablecertifi‐ │ {true|false}, indi‐ │
9789 │ABLECERTIFICATERE‐ │ caterevocationcheck │ cates if revocation │
9790 │VOCATIONCHECK │ │ checking (CRL / │
9791 │ │ │ OCSP) should be │
9792 │ │ │ disabled. │
9793 ├────────────────────┼─────────────────────┼─────────────────────┤
9794 │MONGOC_URI_TLSDIS‐ │ tlsdisableocspend‐ │ {true|false}, indi‐ │
9795 │ABLEOCSPEND‐ │ pointcheck │ cates if OCSP re‐ │
9796 │POINTCHECK │ │ sponder endpoints │
9797 │ │ │ should not be re‐ │
9798 │ │ │ quested when an │
9799 │ │ │ OCSP response is │
9800 │ │ │ not stapled. │
9801 └────────────────────┴─────────────────────┴─────────────────────┘
9802
9803 See Configuring TLS for details about these options and about building
9804 libmongoc with TLS support.
9805
9806 Deprecated SSL Options
9807 The following options have been deprecated and may be removed from fu‐
9808 ture releases of libmongoc.
9809
9810 ┌──────────────────────┬──────────────────┬───────────────────┬──────────────────┐
9811 │Constant │ Key │ Deprecated For │ Key │
9812 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9813 │MONGOC_URI_SSL │ ssl │ MONGOC_URI_TLS │ tls │
9814 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9815 │MON‐ │ sslclientcer‐ │ MON‐ │ tlscertifi‐ │
9816 │GOC_URI_SSLCLIENTCER‐ │ tificatekeyfile │ GOC_URI_TLSCER‐ │ catekeyfile │
9817 │TIFICATEKEYFILE │ │ TIFICATEKEYFILE │ │
9818 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9819 │MON‐ │ sslclientcer‐ │ MON‐ │ tlscertifi‐ │
9820 │GOC_URI_SSLCLIENTCER‐ │ tificatekeypass‐ │ GOC_URI_TLSCER‐ │ catekeypassword │
9821 │TIFICATEKEYPASSWORD │ word │ TIFICATEKEY‐ │ │
9822 │ │ │ FILEPASSWORD │ │
9823 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9824 │MONGOC_URI_SSLCER‐ │ sslcertifi‐ │ MON‐ │ tlscafile │
9825 │TIFICATEAUTHORITYFILE │ cateauthority‐ │ GOC_URI_TLSCAFILE │ │
9826 │ │ file │ │ │
9827 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9828 │MONGOC_URI_SSLALLOW‐ │ sslallowinvalid‐ │ MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │
9829 │INVALIDCERTIFICATES │ certificates │ LOWINVALIDCER‐ │ certificates │
9830 │ │ │ TIFICATES │ │
9831 ├──────────────────────┼──────────────────┼───────────────────┼──────────────────┤
9832 │MONGOC_URI_SSLALLOW‐ │ sslallowinvalid‐ │ MONGOC_URI_TLSAL‐ │ tlsallowinvalid‐ │
9833 │INVALIDHOSTNAMES │ hostnames │ LOWINVALIDHOST‐ │ hostnames │
9834 │ │ │ NAMES │ │
9835 └──────────────────────┴──────────────────┴───────────────────┴──────────────────┘
9836
9837 Server Discovery, Monitoring, and Selection Options
9838 Clients in a mongoc_client_pool_t share a topology scanner that runs on
9839 a background thread. The thread wakes every heartbeatFrequencyMS (de‐
9840 fault 10 seconds) to scan all MongoDB servers in parallel. Whenever an
9841 application operation requires a server that is not known--for example,
9842 if there is no known primary and your application attempts an in‐
9843 sert--the thread rescans all servers every half-second. In this situa‐
9844 tion the pooled client waits up to serverSelectionTimeoutMS (default 30
9845 seconds) for the thread to find a server suitable for the operation,
9846 then returns an error with domain MONGOC_ERROR_SERVER_SELECTION.
9847
9848 Technically, the total time an operation may wait while a pooled client
9849 scans the topology is controlled both by serverSelectionTimeoutMS and
9850 connectTimeoutMS. The longest wait occurs if the last scan begins just
9851 at the end of the selection timeout, and a slow or down server requires
9852 the full connection timeout before the client gives up.
9853
9854 A non-pooled client is single-threaded. Every heartbeatFrequencyMS, it
9855 blocks the next application operation while it does a parallel scan.
9856 This scan takes as long as needed to check the slowest server: roughly
9857 connectTimeoutMS. Therefore the default heartbeatFrequencyMS for sin‐
9858 gle-threaded clients is greater than for pooled clients: 60 seconds.
9859
9860 By default, single-threaded (non-pooled) clients scan only once when an
9861 operation requires a server that is not known. If you attempt an insert
9862 and there is no known primary, the client checks all servers once try‐
9863 ing to find it, then succeeds or returns an error with domain MON‐
9864 GOC_ERROR_SERVER_SELECTION. But if you set serverSelectionTryOnce to
9865 "false", the single-threaded client loops, checking all servers every
9866 half-second, until serverSelectionTimeoutMS.
9867
9868 The total time an operation may wait for a single-threaded client to
9869 scan the topology is determined by connectTimeoutMS in the try-once
9870 case, or serverSelectionTimeoutMS and connectTimeoutMS if serverSelec‐
9871 tionTryOnce is set "false".
9872
9873 ┌────────────────────┬─────────────────────┬─────────────────────┐
9874 │Constant │ Key │ Description │
9875 ├────────────────────┼─────────────────────┼─────────────────────┤
9876 │MONGOC_URI_HEART‐ │ heartbeatfrequen‐ │ The interval be‐ │
9877 │BEATFREQUENCYMS │ cyms │ tween server moni‐ │
9878 │ │ │ toring checks. De‐ │
9879 │ │ │ faults to 10,000ms │
9880 │ │ │ (10 seconds) in │
9881 │ │ │ pooled │
9882 │ │ │ (multi-threaded) │
9883 │ │ │ mode, 60,000ms (60 │
9884 │ │ │ seconds) in │
9885 │ │ │ non-pooled mode │
9886 │ │ │ (single-threaded). │
9887 ├────────────────────┼─────────────────────┼─────────────────────┤
9888 │MONGOC_URI_SERVERS‐ │ serverselection‐ │ A timeout in mil‐ │
9889 │ELECTIONTIMEOUTMS │ timeoutms │ liseconds to block │
9890 │ │ │ for server selec‐ │
9891 │ │ │ tion before throw‐ │
9892 │ │ │ ing an exception. │
9893 │ │ │ The default is │
9894 │ │ │ 30,0000ms (30 sec‐ │
9895 │ │ │ onds). │
9896 └────────────────────┴─────────────────────┴─────────────────────┘
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929 │MONGOC_URI_SERVERS‐ │ serverselectiontry‐ │ If "true", the │
9930 │ELECTIONTRYONCE │ once │ driver scans the │
9931 │ │ │ topology exactly │
9932 │ │ │ once after server │
9933 │ │ │ selection fails, │
9934 │ │ │ then either selects │
9935 │ │ │ a server or returns │
9936 │ │ │ an error. If it is │
9937 │ │ │ false, then the │
9938 │ │ │ driver repeatedly │
9939 │ │ │ searches for a │
9940 │ │ │ suitable server for │
9941 │ │ │ up to serverSelec‐ │
9942 │ │ │ tionTimeoutMS mil‐ │
9943 │ │ │ liseconds (pausing │
9944 │ │ │ a half second be‐ │
9945 │ │ │ tween attempts). │
9946 │ │ │ The default for │
9947 │ │ │ serverSelectionTry‐ │
9948 │ │ │ Once is "false" for │
9949 │ │ │ pooled clients, │
9950 │ │ │ otherwise "true". │
9951 │ │ │ Pooled clients ig‐ │
9952 │ │ │ nore serverSelec‐ │
9953 │ │ │ tionTryOnce; they │
9954 │ │ │ signal the thread │
9955 │ │ │ to rescan the │
9956 │ │ │ topology every │
9957 │ │ │ half-second until │
9958 │ │ │ serverSelection‐ │
9959 │ │ │ TimeoutMS expires. │
9960 ├────────────────────┼─────────────────────┼─────────────────────┤
9961 │MONGOC_URI_SOCK‐ │ socketcheckinter‐ │ Only applies to │
9962 │ETCHECKINTERVALMS │ valms │ single threaded │
9963 │ │ │ clients. If a │
9964 │ │ │ socket has not been │
9965 │ │ │ used within this │
9966 │ │ │ time, its connec‐ │
9967 │ │ │ tion is checked │
9968 │ │ │ with a quick │
9969 │ │ │ "hello" call before │
9970 │ │ │ it is used again. │
9971 │ │ │ Defaults to 5,000ms │
9972 │ │ │ (5 seconds). │
9973 ├────────────────────┼─────────────────────┼─────────────────────┤
9974 │MONGOC_URI_DIRECT‐ │ directconnection │ If "true", the │
9975 │CONNECTION │ │ driver connects to │
9976 │ │ │ a single server di‐ │
9977 │ │ │ rectly and will not │
9978 │ │ │ monitor additional │
9979 │ │ │ servers. If │
9980 │ │ │ "false", the driver │
9981 │ │ │ connects based on │
9982 │ │ │ the presence and │
9983 │ │ │ value of the repli‐ │
9984 │ │ │ caSet option. │
9985 └────────────────────┴─────────────────────┴─────────────────────┘
9986
9987 Setting any of the *TimeoutMS options above to 0 will be interpreted as
9988 "use the default value".
9989
9990 Connection Pool Options
9991 These options govern the behavior of a mongoc_client_pool_t. They are
9992 ignored by a non-pooled mongoc_client_t.
9993
9994 ┌────────────────────┬────────────────────┬──────────────────────────┐
9995 │Constant │ Key │ Description │
9996 └────────────────────┴────────────────────┴──────────────────────────┘
9997
9998
9999
10000
10001
10002
10003
10004
10005 │MONGOC_URI_MAXPOOL‐ │ maxpoolsize │ The maximum number │
10006 │SIZE │ │ of clients created │
10007 │ │ │ by a │
10008 │ │ │ mongoc_client_pool_t │
10009 │ │ │ total (both in the │
10010 │ │ │ pool and checked │
10011 │ │ │ out). The default │
10012 │ │ │ value is 100. Once │
10013 │ │ │ it is reached, │
10014 │ │ │ mongoc_client_pool_pop() │
10015 │ │ │ blocks until an‐ │
10016 │ │ │ other thread pushes │
10017 │ │ │ a client. │
10018 ├────────────────────┼────────────────────┼──────────────────────────┤
10019 │MONGOC_URI_MINPOOL‐ │ minpoolsize │ Deprecated. This op‐ │
10020 │SIZE │ │ tion's behavior does not │
10021 │ │ │ match its name, and its │
10022 │ │ │ actual behavior will │
10023 │ │ │ likely hurt performance. │
10024 ├────────────────────┼────────────────────┼──────────────────────────┤
10025 │MONGOC_URI_MAXIDLE‐ │ maxidletimems │ Not implemented. │
10026 │TIMEMS │ │ │
10027 ├────────────────────┼────────────────────┼──────────────────────────┤
10028 │MONGOC_URI_WAIT‐ │ waitqueuemultiple │ Not implemented. │
10029 │QUEUEMULTIPLE │ │ │
10030 ├────────────────────┼────────────────────┼──────────────────────────┤
10031 │MONGOC_URI_WAIT‐ │ waitqueuetimeoutms │ The maximum time to wait │
10032 │QUEUETIMEOUTMS │ │ for a client to become │
10033 │ │ │ available from the pool. │
10034 └────────────────────┴────────────────────┴──────────────────────────┘
10035
10036 Write Concern Options
10037 ┌───────────────────┬────────────┬─────────────────────┐
10038 │Constant │ Key │ Description │
10039 └───────────────────┴────────────┴─────────────────────┘
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081 MONGOC_URI_W w Determines the
10082 write concern
10083 (guarantee). Valid
10084 values:
10085
10086 • 0 = The
10087 driver
10088 will not
10089 acknowl‐
10090 edge write
10091 operations
10092 but will
10093 pass or
10094 handle any
10095 network
10096 and socket
10097 errors
10098 that it
10099 receives
10100 to the
10101 client. If
10102 you dis‐
10103 able write
10104 concern
10105 but enable
10106 the get‐
10107 LastError
10108 command’s
10109 w option,
10110 w over‐
10111 rides the
10112 w option.
10113
10114 • 1 = Pro‐
10115 vides ba‐
10116 sic ac‐
10117 knowledge‐
10118 ment of
10119 write op‐
10120 erations.
10121 By speci‐
10122 fying 1,
10123 you re‐
10124 quire that
10125 a stand‐
10126 alone mon‐
10127 god in‐
10128 stance, or
10129 the pri‐
10130 mary for
10131 replica
10132 sets, ac‐
10133 knowledge
10134 all write
10135 opera‐
10136 tions. For
10137 drivers
10138 released
10139 after the
10140 default
10141 write con‐
10142 cern
10143 change,
10144 this is
10145 the de‐
10146 fault
10147 write con‐
10148 cern set‐
10149 ting.
10150
10151 • majority =
10152 For
10153 replica
10154 sets, if
10155 you spec‐
10156 ify the
10157 special
10158 majority
10159 value to w
10160 option,
10161 write op‐
10162 erations
10163 will only
10164 return
10165 success‐
10166 fully af‐
10167 ter a ma‐
10168 jority of
10169 the con‐
10170 figured
10171 replica
10172 set mem‐
10173 bers have
10174 acknowl‐
10175 edged the
10176 write op‐
10177 eration.
10178
10179 • n = For
10180 replica
10181 sets, if
10182 you spec‐
10183 ify a num‐
10184 ber n
10185 greater
10186 than 1,
10187 operations
10188 with this
10189 write con‐
10190 cern re‐
10191 turn only
10192 after n
10193 members of
10194 the set
10195 have ac‐
10196 knowledged
10197 the write.
10198 If you set
10199 n to a
10200 number
10201 that is
10202 greater
10203 than the
10204 number of
10205 available
10206 set mem‐
10207 bers or
10208 members
10209 that hold
10210 data, Mon‐
10211 goDB will
10212 wait, po‐
10213 tentially
10214 indefi‐
10215 nitely,
10216 for these
10217 members to
10218 become
10219 available.
10220
10221 • tags = For
10222 replica
10223 sets, you
10224 can spec‐
10225 ify a tag
10226 set to re‐
10227 quire that
10228 all mem‐
10229 bers of
10230 the set
10231 that have
10232 these tags
10233 configured
10234 return
10235 confirma‐
10236 tion of
10237 the write
10238 operation.
10239 ├───────────────────┼────────────┼─────────────────────┤
10240 │MONGOC_URI_WTIME‐ │ wtimeoutms │ The time in mil‐ │
10241 │OUTMS │ │ liseconds to wait │
10242 │ │ │ for replication to │
10243 │ │ │ succeed, as speci‐ │
10244 │ │ │ fied in the w op‐ │
10245 │ │ │ tion, before timing │
10246 │ │ │ out. When wtime‐ │
10247 │ │ │ outMS is 0, write │
10248 │ │ │ operations will │
10249 │ │ │ never time out. │
10250 ├───────────────────┼────────────┼─────────────────────┤
10251 │MONGOC_URI_JOURNAL │ journal │ Controls whether │
10252 │ │ │ write operations │
10253 │ │ │ will wait until the │
10254 │ │ │ mongod acknowledges │
10255 │ │ │ the write opera‐ │
10256 │ │ │ tions and commits │
10257 │ │ │ the data to the on │
10258 │ │ │ disk journal. │
10259 │ │ │ │
10260 │ │ │ • true = │
10261 │ │ │ Enables │
10262 │ │ │ journal │
10263 │ │ │ commit ac‐ │
10264 │ │ │ knowledge‐ │
10265 │ │ │ ment write │
10266 │ │ │ concern. │
10267 │ │ │ Equivalent │
10268 │ │ │ to speci‐ │
10269 │ │ │ fying the │
10270 │ │ │ getLastEr‐ │
10271 │ │ │ ror com‐ │
10272 │ │ │ mand with │
10273 │ │ │ the j op‐ │
10274 │ │ │ tion en‐ │
10275 │ │ │ abled. │
10276 │ │ │ │
10277 │ │ │ • false = │
10278 │ │ │ Does not │
10279 │ │ │ require │
10280 │ │ │ that mon‐ │
10281 │ │ │ god commit │
10282 │ │ │ write op‐ │
10283 │ │ │ erations │
10284 │ │ │ to the │
10285 │ │ │ journal │
10286 │ │ │ before ac‐ │
10287 │ │ │ knowledg‐ │
10288 │ │ │ ing the │
10289 │ │ │ write op‐ │
10290 │ │ │ eration. │
10291 │ │ │ This is │
10292 │ │ │ the de‐ │
10293 │ │ │ fault op‐ │
10294 │ │ │ tion for │
10295 │ │ │ the jour‐ │
10296 │ │ │ nal param‐ │
10297 │ │ │ eter. │
10298 └───────────────────┴────────────┴─────────────────────┘
10299
10300 Read Concern Options
10301 ┌────────────────────┬──────────────────┬─────────────────────┐
10302 │Constant │ Key │ Description │
10303 └────────────────────┴──────────────────┴─────────────────────┘
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315 │MONGOC_URI_READCON‐ │ readconcernlevel │ The level of isola‐ │
10316 │CERNLEVEL │ │ tion for read oper‐ │
10317 │ │ │ ations. If the │
10318 │ │ │ level is left un‐ │
10319 │ │ │ specified, the │
10320 │ │ │ server default will │
10321 │ │ │ be used. See │
10322 │ │ │ readConcern in the │
10323 │ │ │ MongoDB Manual for │
10324 │ │ │ details. │
10325 └────────────────────┴──────────────────┴─────────────────────┘
10326
10327 Read Preference Options
10328 When connected to a replica set, the driver chooses which member to
10329 query using the read preference:
10330
10331 1. Choose members whose type matches "readPreference".
10332
10333 2. From these, if there are any tags sets configured, choose members
10334 matching the first tag set. If there are none, fall back to the next
10335 tag set and so on, until some members are chosen or the tag sets are
10336 exhausted.
10337
10338 3. From the chosen servers, distribute queries randomly among the
10339 server with the fastest round-trip times. These include the server
10340 with the fastest time and any whose round-trip time is no more than
10341 "localThresholdMS" slower.
10342
10343 ┌────────────────────┬─────────────────────┬─────────────────────┐
10344 │Constant │ Key │ Description │
10345 ├────────────────────┼─────────────────────┼─────────────────────┤
10346 │MONGOC_URI_READ‐ │ readpreference │ Specifies the │
10347 │PREFERENCE │ │ replica set read │
10348 │ │ │ preference for this │
10349 │ │ │ connection. This │
10350 │ │ │ setting overrides │
10351 │ │ │ any secondaryOk │
10352 │ │ │ value. The read │
10353 │ │ │ preference values │
10354 │ │ │ are the following: │
10355 │ │ │ │
10356 │ │ │ • primary │
10357 │ │ │ (default) │
10358 │ │ │ │
10359 │ │ │ • prima‐ │
10360 │ │ │ ryPre‐ │
10361 │ │ │ ferred │
10362 │ │ │ │
10363 │ │ │ • secondary │
10364 │ │ │ │
10365 │ │ │ • sec‐ │
10366 │ │ │ ondaryPre‐ │
10367 │ │ │ ferred │
10368 │ │ │ │
10369 │ │ │ • nearest │
10370 ├────────────────────┼─────────────────────┼─────────────────────┤
10371 │MONGOC_URI_READ‐ │ readpreferencetags │ A representation of │
10372 │PREFERENCETAGS │ │ a tag set. See also │
10373 │ │ │ Tag Sets. │
10374 ├────────────────────┼─────────────────────┼─────────────────────┤
10375 │MONGOC_URI_LO‐ │ localthresholdms │ How far to distrib‐ │
10376 │CALTHRESHOLDMS │ │ ute queries, beyond │
10377 │ │ │ the server with the │
10378 │ │ │ fastest round-trip │
10379 │ │ │ time. By default, │
10380 │ │ │ only servers within │
10381 │ │ │ 15ms of the fastest │
10382 │ │ │ round-trip time re‐ │
10383 │ │ │ ceive queries. │
10384 └────────────────────┴─────────────────────┴─────────────────────┘
10385
10386
10387
10388
10389
10390
10391 │MONGOC_URI_MAXSTAL‐ │ maxstalenessseconds │ The maximum repli‐ │
10392 │ENESSSECONDS │ │ cation lag, in wall │
10393 │ │ │ clock time, that a │
10394 │ │ │ secondary can suf‐ │
10395 │ │ │ fer and still be │
10396 │ │ │ eligible. The │
10397 │ │ │ smallest allowed │
10398 │ │ │ value for maxStale‐ │
10399 │ │ │ nessSeconds is 90 │
10400 │ │ │ seconds. │
10401 └────────────────────┴─────────────────────┴─────────────────────┘
10402
10403 NOTE:
10404 When connecting to more than one mongos, libmongoc's localThresh‐
10405 oldMS applies only to the selection of mongos servers. The threshold
10406 for selecting among replica set members in shards is controlled by
10407 the mongos's localThreshold command line option.
10408
10409 Legacy Options
10410 For historical reasons, the following options are available. They
10411 should however not be used.
10412
10413 ┌────────────────┬──────┬─────────────────────┐
10414 │Constant │ Key │ Description │
10415 ├────────────────┼──────┼─────────────────────┤
10416 │MONGOC_URI_SAFE │ safe │ {true|false} Same │
10417 │ │ │ as w={1|0} │
10418 └────────────────┴──────┴─────────────────────┘
10419
10420 Version Checks
10421 Conditional compilation based on mongoc version
10422
10423 Description
10424 The following preprocessor macros can be used to perform various checks
10425 based on the version of the library you are compiling against. This
10426 may be useful if you only want to enable a feature on a certain version
10427 of the library.
10428
10429 #include <mongoc/mongoc.h>
10430
10431 #define MONGOC_MAJOR_VERSION (x)
10432 #define MONGOC_MINOR_VERSION (y)
10433 #define MONGOC_MICRO_VERSION (z)
10434 #define MONGOC_VERSION_S "x.y.z"
10435 #define MONGOC_VERSION_HEX ((1 << 24) | (0 << 16) | (0 << 8) | 0)
10436 #define MONGOC_CHECK_VERSION(major, minor, micro)
10437
10438 Only compile a block on MongoDB C Driver 1.1.0 and newer.
10439
10440 #if MONGOC_CHECK_VERSION(1, 1, 0)
10441 static void
10442 do_something (void)
10443 {
10444 }
10445 #endif
10446
10447 mongoc_write_concern_t
10448 Write Concern abstraction
10449
10450 Synopsis
10451 mongoc_write_concern_t tells the driver what level of acknowledgement
10452 to await from the server. The default, MONGOC_WRITE_CONCERN_W_DEFAULT,
10453 is right for the great majority of applications.
10454
10455 You can specify a write concern on connection objects, database ob‐
10456 jects, collection objects, or per-operation. Data-modifying operations
10457 typically use the write concern of the object they operate on, and
10458 check the server response for a write concern error or write concern
10459 timeout. For example, mongoc_collection_drop_index() uses the collec‐
10460 tion's write concern, and a write concern error or timeout in the re‐
10461 sponse is considered a failure.
10462
10463 Exceptions to this principle are the generic command functions:
10464
10465 • mongoc_client_command()
10466
10467 • mongoc_client_command_simple()
10468
10469 • mongoc_database_command()
10470
10471 • mongoc_database_command_simple()
10472
10473 • mongoc_collection_command()
10474
10475 • mongoc_collection_command_simple()
10476
10477 These generic command functions do not automatically apply a write con‐
10478 cern, and they do not check the server response for a write concern er‐
10479 ror or write concern timeout.
10480
10481 See Write Concern on the MongoDB website for more information.
10482
10483 Write Concern Levels
10484 Set the write concern level with mongoc_write_concern_set_w().
10485
10486 ┌───────────────────────────┬────────────────────────────┐
10487 │MONGOC_WRITE_CONCERN_W_DE‐ │ By default, writes block │
10488 │FAULT (1) │ awaiting acknowledgement │
10489 │ │ from MongoDB. Acknowledged │
10490 │ │ write concern allows │
10491 │ │ clients to catch network, │
10492 │ │ duplicate key, and other │
10493 │ │ errors. │
10494 ├───────────────────────────┼────────────────────────────┤
10495 │MONGOC_WRITE_CONCERN_W_UN‐ │ With this write concern, │
10496 │ACKNOWLEDGED (0) │ MongoDB does not acknowl‐ │
10497 │ │ edge the receipt of write │
10498 │ │ operation. Unacknowledged │
10499 │ │ is similar to errors ig‐ │
10500 │ │ nored; however, mongoc at‐ │
10501 │ │ tempts to receive and han‐ │
10502 │ │ dle network errors when │
10503 │ │ possible. │
10504 ├───────────────────────────┼────────────────────────────┤
10505 │MONGOC_WRITE_CONCERN_W_MA‐ │ Block until a write has │
10506 │JORITY (majority) │ been propagated to a ma‐ │
10507 │ │ jority of the nodes in the │
10508 │ │ replica set. │
10509 ├───────────────────────────┼────────────────────────────┤
10510 │n │ Block until a write has │
10511 │ │ been propagated to at │
10512 │ │ least n nodes in the │
10513 │ │ replica set. │
10514 └───────────────────────────┴────────────────────────────┘
10515
10516 Deprecations
10517 The write concern MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED (value -1) is a
10518 deprecated synonym for MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED (value 0),
10519 and will be removed in the next major release.
10520
10521 mongoc_write_concern_set_fsync() is deprecated.
10522
10523 Application Performance Monitoring (APM)
10524 The MongoDB C Driver allows you to monitor all the MongoDB operations
10525 the driver executes. This event-notification system conforms to two
10526 MongoDB driver specs:
10527
10528 • Command Logging and Monitoring: events related to all application op‐
10529 erations.
10530
10531 • SDAM Monitoring: events related to the driver's Server Discovery And
10532 Monitoring logic.
10533
10534 To receive notifications, create a mongoc_apm_callbacks_t with
10535 mongoc_apm_callbacks_new(), set callbacks on it, then pass it to
10536 mongoc_client_set_apm_callbacks() or
10537 mongoc_client_pool_set_apm_callbacks().
10538
10539 Command-Monitoring Example
10540 example-command-monitoring.c
10541
10542 /* gcc example-command-monitoring.c -o example-command-monitoring \
10543 * $(pkg-config --cflags --libs libmongoc-1.0) */
10544
10545 /* ./example-command-monitoring [CONNECTION_STRING] */
10546
10547 #include <mongoc/mongoc.h>
10548 #include <stdio.h>
10549
10550
10551 typedef struct {
10552 int started;
10553 int succeeded;
10554 int failed;
10555 } stats_t;
10556
10557
10558 void
10559 command_started (const mongoc_apm_command_started_t *event)
10560 {
10561 char *s;
10562
10563 s = bson_as_relaxed_extended_json (
10564 mongoc_apm_command_started_get_command (event), NULL);
10565 printf ("Command %s started on %s:\n%s\n\n",
10566 mongoc_apm_command_started_get_command_name (event),
10567 mongoc_apm_command_started_get_host (event)->host,
10568 s);
10569
10570 ((stats_t *) mongoc_apm_command_started_get_context (event))->started++;
10571
10572 bson_free (s);
10573 }
10574
10575
10576 void
10577 command_succeeded (const mongoc_apm_command_succeeded_t *event)
10578 {
10579 char *s;
10580
10581 s = bson_as_relaxed_extended_json (
10582 mongoc_apm_command_succeeded_get_reply (event), NULL);
10583 printf ("Command %s succeeded:\n%s\n\n",
10584 mongoc_apm_command_succeeded_get_command_name (event),
10585 s);
10586
10587 ((stats_t *) mongoc_apm_command_succeeded_get_context (event))->succeeded++;
10588
10589 bson_free (s);
10590 }
10591
10592
10593 void
10594 command_failed (const mongoc_apm_command_failed_t *event)
10595 {
10596 bson_error_t error;
10597
10598 mongoc_apm_command_failed_get_error (event, &error);
10599 printf ("Command %s failed:\n\"%s\"\n\n",
10600 mongoc_apm_command_failed_get_command_name (event),
10601 error.message);
10602
10603 ((stats_t *) mongoc_apm_command_failed_get_context (event))->failed++;
10604 }
10605
10606
10607 int
10608 main (int argc, char *argv[])
10609 {
10610 mongoc_client_t *client;
10611 mongoc_apm_callbacks_t *callbacks;
10612 stats_t stats = {0};
10613 mongoc_collection_t *collection;
10614 bson_error_t error;
10615 const char *uri_string =
10616 "mongodb://127.0.0.1/?appname=cmd-monitoring-example";
10617 mongoc_uri_t *uri;
10618 const char *collection_name = "test";
10619 bson_t *docs[2];
10620
10621 mongoc_init ();
10622
10623 if (argc > 1) {
10624 uri_string = argv[1];
10625 }
10626
10627 uri = mongoc_uri_new_with_error (uri_string, &error);
10628 if (!uri) {
10629 fprintf (stderr,
10630 "failed to parse URI: %s\n"
10631 "error message: %s\n",
10632 uri_string,
10633 error.message);
10634 return EXIT_FAILURE;
10635 }
10636
10637 client = mongoc_client_new_from_uri (uri);
10638 if (!client) {
10639 return EXIT_FAILURE;
10640 }
10641
10642 mongoc_client_set_error_api (client, 2);
10643 callbacks = mongoc_apm_callbacks_new ();
10644 mongoc_apm_set_command_started_cb (callbacks, command_started);
10645 mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded);
10646 mongoc_apm_set_command_failed_cb (callbacks, command_failed);
10647 mongoc_client_set_apm_callbacks (
10648 client, callbacks, (void *) &stats /* context pointer */);
10649
10650 collection = mongoc_client_get_collection (client, "test", collection_name);
10651 mongoc_collection_drop (collection, NULL);
10652
10653 docs[0] = BCON_NEW ("_id", BCON_INT32 (0));
10654 docs[1] = BCON_NEW ("_id", BCON_INT32 (1));
10655 mongoc_collection_insert_many (
10656 collection, (const bson_t **) docs, 2, NULL, NULL, NULL);
10657
10658 /* duplicate key error on the second insert */
10659 mongoc_collection_insert_one (collection, docs[0], NULL, NULL, NULL);
10660
10661 mongoc_collection_destroy (collection);
10662 mongoc_apm_callbacks_destroy (callbacks);
10663 mongoc_uri_destroy (uri);
10664 mongoc_client_destroy (client);
10665
10666 printf ("started: %d\nsucceeded: %d\nfailed: %d\n",
10667 stats.started,
10668 stats.succeeded,
10669 stats.failed);
10670
10671 bson_destroy (docs[0]);
10672 bson_destroy (docs[1]);
10673
10674 mongoc_cleanup ();
10675
10676 return EXIT_SUCCESS;
10677 }
10678
10679
10680 This example program prints:
10681
10682 Command drop started on 127.0.0.1:
10683 { "drop" : "test" }
10684
10685 Command drop succeeded:
10686 { "ns" : "test.test", "nIndexesWas" : 1, "ok" : 1.0 }
10687
10688 Command insert started on 127.0.0.1:
10689 {
10690 "insert" : "test",
10691 "ordered" : true,
10692 "documents" : [
10693 { "_id" : 0 }, { "_id" : 1 }
10694 ]
10695 }
10696
10697 Command insert succeeded:
10698 { "n" : 2, "ok" : 1.0 }
10699
10700 Command insert started on 127.0.0.1:
10701 {
10702 "insert" : "test",
10703 "ordered" : true,
10704 "documents" : [
10705 { "_id" : 0 }
10706 ]
10707 }
10708
10709 Command insert succeeded:
10710 {
10711 "n" : 0,
10712 "writeErrors" : [
10713 { "index" : 0, "code" : 11000, "errmsg" : "duplicate key" }
10714 ],
10715 "ok" : 1.0
10716 }
10717
10718 started: 3
10719 succeeded: 3
10720 failed: 0
10721
10722 The output has been edited and formatted for clarity. Depending on your
10723 server configuration, messages may include metadata like database name,
10724 logical session ids, or cluster times that are not shown here.
10725
10726 The final "insert" command is considered successful, despite the
10727 writeError, because the server replied to the overall command with
10728 "ok": 1.
10729
10730 SDAM Monitoring Example
10731 example-sdam-monitoring.c
10732
10733 /* gcc example-sdam-monitoring.c -o example-sdam-monitoring \
10734 * $(pkg-config --cflags --libs libmongoc-1.0) */
10735
10736 /* ./example-sdam-monitoring [CONNECTION_STRING] */
10737
10738 #include <mongoc/mongoc.h>
10739 #include <stdio.h>
10740
10741
10742 typedef struct {
10743 int server_changed_events;
10744 int server_opening_events;
10745 int server_closed_events;
10746 int topology_changed_events;
10747 int topology_opening_events;
10748 int topology_closed_events;
10749 int heartbeat_started_events;
10750 int heartbeat_succeeded_events;
10751 int heartbeat_failed_events;
10752 } stats_t;
10753
10754
10755 static void
10756 server_changed (const mongoc_apm_server_changed_t *event)
10757 {
10758 stats_t *context;
10759 const mongoc_server_description_t *prev_sd, *new_sd;
10760
10761 context = (stats_t *) mongoc_apm_server_changed_get_context (event);
10762 context->server_changed_events++;
10763
10764 prev_sd = mongoc_apm_server_changed_get_previous_description (event);
10765 new_sd = mongoc_apm_server_changed_get_new_description (event);
10766
10767 printf ("server changed: %s %s -> %s\n",
10768 mongoc_apm_server_changed_get_host (event)->host_and_port,
10769 mongoc_server_description_type (prev_sd),
10770 mongoc_server_description_type (new_sd));
10771 }
10772
10773
10774 static void
10775 server_opening (const mongoc_apm_server_opening_t *event)
10776 {
10777 stats_t *context;
10778
10779 context = (stats_t *) mongoc_apm_server_opening_get_context (event);
10780 context->server_opening_events++;
10781
10782 printf ("server opening: %s\n",
10783 mongoc_apm_server_opening_get_host (event)->host_and_port);
10784 }
10785
10786
10787 static void
10788 server_closed (const mongoc_apm_server_closed_t *event)
10789 {
10790 stats_t *context;
10791
10792 context = (stats_t *) mongoc_apm_server_closed_get_context (event);
10793 context->server_closed_events++;
10794
10795 printf ("server closed: %s\n",
10796 mongoc_apm_server_closed_get_host (event)->host_and_port);
10797 }
10798
10799
10800 static void
10801 topology_changed (const mongoc_apm_topology_changed_t *event)
10802 {
10803 stats_t *context;
10804 const mongoc_topology_description_t *prev_td;
10805 const mongoc_topology_description_t *new_td;
10806 mongoc_server_description_t **prev_sds;
10807 size_t n_prev_sds;
10808 mongoc_server_description_t **new_sds;
10809 size_t n_new_sds;
10810 size_t i;
10811 mongoc_read_prefs_t *prefs;
10812
10813 context = (stats_t *) mongoc_apm_topology_changed_get_context (event);
10814 context->topology_changed_events++;
10815
10816 prev_td = mongoc_apm_topology_changed_get_previous_description (event);
10817 prev_sds = mongoc_topology_description_get_servers (prev_td, &n_prev_sds);
10818 new_td = mongoc_apm_topology_changed_get_new_description (event);
10819 new_sds = mongoc_topology_description_get_servers (new_td, &n_new_sds);
10820
10821 printf ("topology changed: %s -> %s\n",
10822 mongoc_topology_description_type (prev_td),
10823 mongoc_topology_description_type (new_td));
10824
10825 if (n_prev_sds) {
10826 printf (" previous servers:\n");
10827 for (i = 0; i < n_prev_sds; i++) {
10828 printf (" %s %s\n",
10829 mongoc_server_description_type (prev_sds[i]),
10830 mongoc_server_description_host (prev_sds[i])->host_and_port);
10831 }
10832 }
10833
10834 if (n_new_sds) {
10835 printf (" new servers:\n");
10836 for (i = 0; i < n_new_sds; i++) {
10837 printf (" %s %s\n",
10838 mongoc_server_description_type (new_sds[i]),
10839 mongoc_server_description_host (new_sds[i])->host_and_port);
10840 }
10841 }
10842
10843 prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);
10844
10845 /* it is safe, and unfortunately necessary, to cast away const here */
10846 if (mongoc_topology_description_has_readable_server (
10847 (mongoc_topology_description_t *) new_td, prefs)) {
10848 printf (" secondary AVAILABLE\n");
10849 } else {
10850 printf (" secondary UNAVAILABLE\n");
10851 }
10852
10853 if (mongoc_topology_description_has_writable_server (
10854 (mongoc_topology_description_t *) new_td)) {
10855 printf (" primary AVAILABLE\n");
10856 } else {
10857 printf (" primary UNAVAILABLE\n");
10858 }
10859
10860 mongoc_read_prefs_destroy (prefs);
10861 mongoc_server_descriptions_destroy_all (prev_sds, n_prev_sds);
10862 mongoc_server_descriptions_destroy_all (new_sds, n_new_sds);
10863 }
10864
10865
10866 static void
10867 topology_opening (const mongoc_apm_topology_opening_t *event)
10868 {
10869 stats_t *context;
10870
10871 context = (stats_t *) mongoc_apm_topology_opening_get_context (event);
10872 context->topology_opening_events++;
10873
10874 printf ("topology opening\n");
10875 }
10876
10877
10878 static void
10879 topology_closed (const mongoc_apm_topology_closed_t *event)
10880 {
10881 stats_t *context;
10882
10883 context = (stats_t *) mongoc_apm_topology_closed_get_context (event);
10884 context->topology_closed_events++;
10885
10886 printf ("topology closed\n");
10887 }
10888
10889
10890 static void
10891 server_heartbeat_started (const mongoc_apm_server_heartbeat_started_t *event)
10892 {
10893 stats_t *context;
10894
10895 context =
10896 (stats_t *) mongoc_apm_server_heartbeat_started_get_context (event);
10897 context->heartbeat_started_events++;
10898
10899 printf ("%s heartbeat started\n",
10900 mongoc_apm_server_heartbeat_started_get_host (event)->host_and_port);
10901 }
10902
10903
10904 static void
10905 server_heartbeat_succeeded (
10906 const mongoc_apm_server_heartbeat_succeeded_t *event)
10907 {
10908 stats_t *context;
10909 char *reply;
10910
10911 context =
10912 (stats_t *) mongoc_apm_server_heartbeat_succeeded_get_context (event);
10913 context->heartbeat_succeeded_events++;
10914
10915 reply = bson_as_canonical_extended_json (
10916 mongoc_apm_server_heartbeat_succeeded_get_reply (event), NULL);
10917
10918 printf (
10919 "%s heartbeat succeeded: %s\n",
10920 mongoc_apm_server_heartbeat_succeeded_get_host (event)->host_and_port,
10921 reply);
10922
10923 bson_free (reply);
10924 }
10925
10926
10927 static void
10928 server_heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event)
10929 {
10930 stats_t *context;
10931 bson_error_t error;
10932
10933 context = (stats_t *) mongoc_apm_server_heartbeat_failed_get_context (event);
10934 context->heartbeat_failed_events++;
10935 mongoc_apm_server_heartbeat_failed_get_error (event, &error);
10936
10937 printf ("%s heartbeat failed: %s\n",
10938 mongoc_apm_server_heartbeat_failed_get_host (event)->host_and_port,
10939 error.message);
10940 }
10941
10942
10943 int
10944 main (int argc, char *argv[])
10945 {
10946 mongoc_client_t *client;
10947 mongoc_apm_callbacks_t *cbs;
10948 stats_t stats = {0};
10949 const char *uri_string =
10950 "mongodb://127.0.0.1/?appname=sdam-monitoring-example";
10951 mongoc_uri_t *uri;
10952 bson_t cmd = BSON_INITIALIZER;
10953 bson_t reply;
10954 bson_error_t error;
10955
10956 mongoc_init ();
10957
10958 if (argc > 1) {
10959 uri_string = argv[1];
10960 }
10961
10962 uri = mongoc_uri_new_with_error (uri_string, &error);
10963 if (!uri) {
10964 fprintf (stderr,
10965 "failed to parse URI: %s\n"
10966 "error message: %s\n",
10967 uri_string,
10968 error.message);
10969 return EXIT_FAILURE;
10970 }
10971
10972 client = mongoc_client_new_from_uri (uri);
10973 if (!client) {
10974 return EXIT_FAILURE;
10975 }
10976
10977 mongoc_client_set_error_api (client, 2);
10978 cbs = mongoc_apm_callbacks_new ();
10979 mongoc_apm_set_server_changed_cb (cbs, server_changed);
10980 mongoc_apm_set_server_opening_cb (cbs, server_opening);
10981 mongoc_apm_set_server_closed_cb (cbs, server_closed);
10982 mongoc_apm_set_topology_changed_cb (cbs, topology_changed);
10983 mongoc_apm_set_topology_opening_cb (cbs, topology_opening);
10984 mongoc_apm_set_topology_closed_cb (cbs, topology_closed);
10985 mongoc_apm_set_server_heartbeat_started_cb (cbs, server_heartbeat_started);
10986 mongoc_apm_set_server_heartbeat_succeeded_cb (cbs,
10987 server_heartbeat_succeeded);
10988 mongoc_apm_set_server_heartbeat_failed_cb (cbs, server_heartbeat_failed);
10989 mongoc_client_set_apm_callbacks (
10990 client, cbs, (void *) &stats /* context pointer */);
10991
10992 /* the driver connects on demand to perform first operation */
10993 BSON_APPEND_INT32 (&cmd, "buildinfo", 1);
10994 mongoc_client_command_simple (client, "admin", &cmd, NULL, &reply, &error);
10995 mongoc_uri_destroy (uri);
10996 mongoc_client_destroy (client);
10997
10998 printf ("Events:\n"
10999 " server changed: %d\n"
11000 " server opening: %d\n"
11001 " server closed: %d\n"
11002 " topology changed: %d\n"
11003 " topology opening: %d\n"
11004 " topology closed: %d\n"
11005 " heartbeat started: %d\n"
11006 " heartbeat succeeded: %d\n"
11007 " heartbeat failed: %d\n",
11008 stats.server_changed_events,
11009 stats.server_opening_events,
11010 stats.server_closed_events,
11011 stats.topology_changed_events,
11012 stats.topology_opening_events,
11013 stats.topology_closed_events,
11014 stats.heartbeat_started_events,
11015 stats.heartbeat_succeeded_events,
11016 stats.heartbeat_failed_events);
11017
11018 bson_destroy (&cmd);
11019 bson_destroy (&reply);
11020 mongoc_apm_callbacks_destroy (cbs);
11021
11022 mongoc_cleanup ();
11023
11024 return EXIT_SUCCESS;
11025 }
11026
11027
11028 Start a 3-node replica set on localhost with set name "rs" and start
11029 the program:
11030
11031 ./example-sdam-monitoring "mongodb://localhost:27017,localhost:27018/?replicaSet=rs"
11032
11033 This example program prints something like:
11034
11035 topology opening
11036 topology changed: Unknown -> ReplicaSetNoPrimary
11037 secondary UNAVAILABLE
11038 primary UNAVAILABLE
11039 server opening: localhost:27017
11040 server opening: localhost:27018
11041 localhost:27017 heartbeat started
11042 localhost:27018 heartbeat started
11043 localhost:27017 heartbeat succeeded: { ... reply ... }
11044 server changed: localhost:27017 Unknown -> RSPrimary
11045 server opening: localhost:27019
11046 topology changed: ReplicaSetNoPrimary -> ReplicaSetWithPrimary
11047 new servers:
11048 RSPrimary localhost:27017
11049 secondary UNAVAILABLE
11050 primary AVAILABLE
11051 localhost:27019 heartbeat started
11052 localhost:27018 heartbeat succeeded: { ... reply ... }
11053 server changed: localhost:27018 Unknown -> RSSecondary
11054 topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
11055 previous servers:
11056 RSPrimary localhost:27017
11057 new servers:
11058 RSPrimary localhost:27017
11059 RSSecondary localhost:27018
11060 secondary AVAILABLE
11061 primary AVAILABLE
11062 localhost:27019 heartbeat succeeded: { ... reply ... }
11063 server changed: localhost:27019 Unknown -> RSSecondary
11064 topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
11065 previous servers:
11066 RSPrimary localhost:27017
11067 RSSecondary localhost:27018
11068 new servers:
11069 RSPrimary localhost:27017
11070 RSSecondary localhost:27018
11071 RSSecondary localhost:27019
11072 secondary AVAILABLE
11073 primary AVAILABLE
11074 topology closed
11075
11076 Events:
11077 server changed: 3
11078 server opening: 3
11079 server closed: 0
11080 topology changed: 4
11081 topology opening: 1
11082 topology closed: 1
11083 heartbeat started: 3
11084 heartbeat succeeded: 3
11085 heartbeat failed: 0
11086
11087 The driver connects to the mongods on ports 27017 and 27018, which were
11088 specified in the URI, and determines which is primary. It also discov‐
11089 ers the third member, "localhost:27019", and adds it to the topology.
11090
11092 MongoDB, Inc
11093
11095 2017-present, MongoDB, Inc
11096
11097
11098
11099
111001.24.3 Aug 17, 2023 MONGOC_REFERENCE(3)