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