Provided by: libmongoc-doc_1.3.1-1_all bug

NAME

       Bulk_Write_Operations - None

BULK INSERT

       New in MongoDB C driver 0.94.2.

       First  we need to fetch a bulk operation handle from the mongoc_collection_t \&. This can be performed in
       either ordered or unordered mode. Unordered mode allows for greater  parallelization  when  working  with
       sharded clusters.

       mongoc_bulk_operation_t *bulk = mongoc_collection_create_bulk_operation (collection, true, write_concern);

       We  can  now start inserting documents to the bulk operation. These will be buffered until we execute the
       operation.

       The  bulk  operation  will  coalesce  insertions  as  a  single  batch  for  each  consecutive  call   to
       mongoc_bulk_operation_insert(3) \&. This creates a pipelined effect when possible.

       NOTE
              The  bulk  operation  API will automatically handle MongoDB servers < 2.6 by speaking the old wire
              protocol. However, some performance degredation may occur.

       To execute the bulk operation and receive the result we call mongoc_bulk_operation_execute(3) \&.

       #include <assert.h>
       #include <bcon.h>
       #include <mongoc.h>
       #include <stdio.h>

       static void
       bulk1 (mongoc_collection_t *collection)
       {
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;
          int i;

          bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);

          for (i = 0; i < 10000; i++) {
             doc = BCON_NEW ("i", BCON_INT32 (i));
             mongoc_bulk_operation_insert (bulk, doc);
             bson_destroy (doc);
          }

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

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

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

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
       }

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

          mongoc_init ();

          client = mongoc_client_new ("mongodb://localhost/");
          collection = mongoc_client_get_collection (client, "test", "test");

          bulk1 (collection);

          mongoc_collection_destroy (collection);
          mongoc_client_destroy (client);

          mongoc_cleanup ();

          return 0;
       }

       Example reply document:

       {"nInserted"   : 10000,
        "nMatched"    : 0,
        "nModified"   : 0,
        "nRemoved"    : 0,
        "nUpserted"   : 0,
        "writeErrors" : []
        "writeConcernErrors" : [] }

MIXED BULK WRITE OPERATIONS

       New in MongoDB C driver 0.94.2

       MongoDB C driver also supports executing mixed bulk write operations. A  batch  of  insert,  update,  and
       remove operations can be executed together using the bulk write operations API.

       NOTE
              Though  the  following  API will work with all versions of MongoDB, it is designed to be used with
              MongoDB versions >= 2.6. Much better bulk insert performance can be achieved with  older  versions
              of MongoDB through the deprecated mongoc_collection_insert_bulk(3) method.

ORDERED BULK WRITE OPERATIONS

       Ordered  bulk  write  operations  are  batched  and  sent  to the server in the order provided for serial
       execution. The reply document describes the type and count of operations performed.

       #include <assert.h>
       #include <bcon.h>
       #include <mongoc.h>
       #include <stdio.h>

       static void
       bulk2 (mongoc_collection_t *collection)
       {
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *query;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;
          int i;

          bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);

          /* Remove everything */
          query = bson_new ();
          mongoc_bulk_operation_remove (bulk, query);
          bson_destroy (query);

          /* Add a few documents */
          for (i = 1; i < 4; i++) {
             doc = BCON_NEW ("_id", BCON_INT32 (i));
             mongoc_bulk_operation_insert (bulk, doc);
             bson_destroy (doc);
          }

          /* {_id: 1} => {$set: {foo: "bar"}} */
          query = BCON_NEW ("_id", BCON_INT32 (1));
          doc = BCON_NEW ("$set", "{", "foo", BCON_UTF8 ("bar"), "}");
          mongoc_bulk_operation_update (bulk, query, doc, false);
          bson_destroy (query);
          bson_destroy (doc);

          /* {_id: 4} => {'$inc': {'j': 1}} (upsert) */
          query = BCON_NEW ("_id", BCON_INT32 (4));
          doc = BCON_NEW ("$inc", "{", "j", BCON_INT32 (1), "}");
          mongoc_bulk_operation_update (bulk, query, doc, true);
          bson_destroy (query);
          bson_destroy (doc);

          /* replace {j:1} with {j:2} */
          query = BCON_NEW ("j", BCON_INT32 (1));
          doc = BCON_NEW ("j", BCON_INT32 (2));
          mongoc_bulk_operation_replace_one (bulk, query, doc, false);
          bson_destroy (query);
          bson_destroy (doc);

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

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

          if (!ret) {
             printf ("Error: %s\n", error.message);
          }

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
       }

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

          mongoc_init ();

          client = mongoc_client_new ("mongodb://localhost/");
          collection = mongoc_client_get_collection (client, "test", "test");

          bulk2 (collection);

          mongoc_collection_destroy (collection);
          mongoc_client_destroy (client);

          mongoc_cleanup ();

          return 0;
       }

       Example reply document:

       { "nInserted"   : 3,
         "nMatched"    : 2,
         "nModified"   : 2,
         "nRemoved"    : 10000,
         "nUpserted"   : 1,
         "upserted"    : [{"index" : 5, "_id" : 4}],
         "writeErrors" : []
         "writeConcernErrors" : [] }

       The index field in the upserted array is the 0‐based index of the upsert operation; in this example,  the
       sixth operation of the overall bulk operation was an upsert, so its index is 5.

       nModified is only reported when using MongoDB 2.6 and later, otherwise the field is omitted.

UNORDERED BULK WRITE OPERATIONS

       Unordered  bulk  write operations are batched and sent to the server in arbitrary order where they may be
       executed in parallel. Any errors that occur are reported after all operations are attempted.

       In the next example the first and third operations fail due to the unique constraint on _id \&. Since  we
       are doing unordered execution the second and fourth operations succeed.

       #include <assert.h>
       #include <bcon.h>
       #include <mongoc.h>
       #include <stdio.h>

       static void
       bulk3 (mongoc_collection_t *collection)
       {
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *query;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;

          /* false indicates unordered */
          bulk = mongoc_collection_create_bulk_operation (collection, false, NULL);

          /* Add a document */
          doc = BCON_NEW ("_id", BCON_INT32 (1));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          /* remove {_id: 2} */
          query = BCON_NEW ("_id", BCON_INT32 (2));
          mongoc_bulk_operation_remove_one (bulk, query);
          bson_destroy (query);

          /* insert {_id: 3} */
          doc = BCON_NEW ("_id", BCON_INT32 (3));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          /* replace {_id:4} {'i': 1} */
          query = BCON_NEW ("_id", BCON_INT32 (4));
          doc = BCON_NEW ("i", BCON_INT32 (1));
          mongoc_bulk_operation_replace_one (bulk, query, doc, false);
          bson_destroy (query);
          bson_destroy (doc);

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

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

          if (!ret) {
             printf ("Error: %s\n", error.message);
          }

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
       }

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

          mongoc_init ();

          client = mongoc_client_new ("mongodb://localhost/");
          collection = mongoc_client_get_collection (client, "test", "test");

          bulk3 (collection);

          mongoc_collection_destroy (collection);
          mongoc_client_destroy (client);

          mongoc_cleanup ();

          return 0;
       }

       Example reply document:

       { "nInserted"    : 0,
         "nMatched"     : 1,
         "nModified"    : 1,
         "nRemoved"     : 1,
         "nUpserted"    : 0,
         "writeErrors"  : [
           { "index"  : 0,
             "code"   : 11000,
             "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }" },
           { "index"  : 2,
             "code"   : 11000,
             "errmsg" : "E11000 duplicate key error index: test.test.$_id_ dup key: { : 3 }" } ],
         "writeConcernErrors" : [] }

       Error: E11000 duplicate key error index: test.test.$_id_ dup key: { : 1 }

       The bson_error_t domain is MONGOC_ERROR_COMMAND and its code is 11000.

BULK OPERATION BYPASSING DOCUMENT VALIDATION

       NOTE
              This feature is only available when using MongoDB 3.2 and later.

       By  default bulk operations are validated against the schema, if any is defined. In certain cases however
       it may be necessary to bypass the document validation.

       #include <assert.h>
       #include <bcon.h>
       #include <mongoc.h>
       #include <stdio.h>

       static void
       bulk5_fail (mongoc_collection_t *collection)
       {
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;

          bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);

          /* Two inserts */
          doc = BCON_NEW ("_id", BCON_INT32 (31));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          doc = BCON_NEW ("_id", BCON_INT32 (32));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          /* The above documents do not comply to the schema validation rules
           * we created previously, so this will result in an error */
          ret = mongoc_bulk_operation_execute (bulk, &reply, &error);

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

          if (!ret) {
             printf ("Error: %s\n", error.message);
          }

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
       }

       static void
       bulk5_success (mongoc_collection_t *collection)
       {
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;

          bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);

          /* Allow this document to bypass document validation.
           * NOTE: When authentication is enabled, the authenticated user must have
           * either the "dbadmin" or "restore" roles to bypass document validation */
          mongoc_bulk_operation_set_bypass_document_validation (bulk, true);

          /* Two inserts */
          doc = BCON_NEW ("_id", BCON_INT32 (31));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          doc = BCON_NEW ("_id", BCON_INT32 (32));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

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

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

          if (!ret) {
             printf ("Error: %s\n", error.message);
          }

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
       }

       int
       main (int argc,
             char *argv[])
       {
          bson_t *options;
          bson_error_t error;
          mongoc_client_t *client;
          mongoc_collection_t *collection;
          mongoc_database_t *database;

          mongoc_init ();

          client = mongoc_client_new ("mongodb://localhost/");
          database = mongoc_client_get_database (client, "testasdf");

          /* Create schema validator */
          options = BCON_NEW ("validator", "{", "number", "{", "$gte", BCON_INT32 (5), "}", "}");
          collection = mongoc_database_create_collection (database, "collname", options, &error);

          if (collection) {
             bulk5_fail (collection);
             bulk5_success (collection);
             mongoc_collection_destroy (collection);
          } else {
             fprintf(stderr, "Couldn't create collection: '%s'\n", error.message);
          }

          bson_free (options);
          mongoc_database_destroy (database);
          mongoc_client_destroy (client);

          mongoc_cleanup ();

          return 0;
       }

       Running the above example will result in:

       { "nInserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "nUpserted" : 0, "writeErrors" : [ { "index" : 0, "code" : 121, "errmsg" : "Document failed validation" } ] }
       Error: Document failed validation
       { "nInserted" : 2, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "nUpserted" : 0, "writeErrors" : [  ] }

       The bson_error_t domain is MONGOC_ERROR_COMMAND \&.

BULK OPERATION WRITE CONCERNS

       By default bulk operations are executed with the  write_concern  of  the  collection  they  are  executed
       against.  A  custom write concern can be passed to the mongoc_collection_create_bulk_operation(3) method.
       Write concern errors (e.g. wtimeout) will be reported after all operations are attempted,  regardless  of
       execution order.

       #include <assert.h>
       #include <bcon.h>
       #include <mongoc.h>
       #include <stdio.h>

       static void
       bulk4 (mongoc_collection_t *collection)
       {
          mongoc_write_concern_t *wc;
          mongoc_bulk_operation_t *bulk;
          bson_error_t error;
          bson_t *doc;
          bson_t reply;
          char *str;
          bool ret;

          wc = mongoc_write_concern_new ();
          mongoc_write_concern_set_w (wc, 4);
          mongoc_write_concern_set_wtimeout (wc, 100);  /* milliseconds */

          bulk = mongoc_collection_create_bulk_operation (collection, true, wc);

          /* Two inserts */
          doc = BCON_NEW ("_id", BCON_INT32 (10));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

          doc = BCON_NEW ("_id", BCON_INT32 (11));
          mongoc_bulk_operation_insert (bulk, doc);
          bson_destroy (doc);

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

          str = bson_as_json (&reply, NULL);
          printf ("%s\n", str);
          bson_free (str);

          if (!ret) {
             printf ("Error: %s\n", error.message);
          }

          bson_destroy (&reply);
          mongoc_bulk_operation_destroy (bulk);
          mongoc_write_concern_destroy (wc);
       }

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

          mongoc_init ();

          client = mongoc_client_new ("mongodb://localhost/");
          collection = mongoc_client_get_collection (client, "test", "test");

          bulk4 (collection);

          mongoc_collection_destroy (collection);
          mongoc_client_destroy (client);

          mongoc_cleanup ();

          return 0;
       }

       Example reply document and error message:

       { "nInserted"    : 2,
         "nMatched"     : 0,
         "nModified"    : 0,
         "nRemoved"     : 0,
         "nUpserted"    : 0,
         "writeErrors"  : [],
         "writeConcernErrors" : [
           { "code"   : 64,
             "errmsg" : "waiting for replication timed out" }
       ] }

       Error: waiting for replication timed out

       The  bson_error_t  domain  is  MONGOC_ERROR_WRITE_CONCERN  if there are write concern errors and no write
       errors. Write errors indicate failed operations, so they take precedence over write concern errors, which
       mean merely that the write concern is not satisfied yet \&.

FURTHER READING

       See the Driver Bulk API Spec , which describes bulk write operations for all MongoDB drivers.

COLOPHON

       This    page    is    part    of    MongoDB    C    Driver.     Please     report     any     bugs     at
       https://jira.mongodb.org/browse/CDRIVER.

MongoDB C Driver                                   2016‐01‐18                           BULK_WRITE_OPERATIONS(3)