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