MONGOC_COMMON_TASK_EXAMPLES(3)

NAME
mongoc_common_task_examples - Common Tasks

Drivers for some other languages provide helper functions to perform certain common tasks. In the C Driver we must explicitly build commands to send to the server.

This snippet contains example code for the explain, copydb and cloneCollection commands.

SETUP

First we'll write some code to insert sample data: doc-common-insert.c.INDENT 0.0

    /* Don't try to compile this file on its own. It's meant to be #included
       by example code */

    /* Insert some sample data */
    bool
    insert_data (mongoc_collection_t *collection)
    {
       mongoc_bulk_operation_t *bulk;
       enum N { ndocs = 4 };
       bson_t *docs[ndocs];
       bson_error_t error;
       int i = 0;
       bool ret;

       bulk = mongoc_collection_create_bulk_operation_with_opts (collection, NULL);

       docs[0] = BCON_NEW ("x", BCON_DOUBLE (1.0), "tags", "[", "dog", "cat", "]");
       docs[1] = BCON_NEW ("x", BCON_DOUBLE (2.0), "tags", "[", "cat", "]");
       docs[2] = BCON_NEW (
          "x", BCON_DOUBLE (2.0), "tags", "[", "mouse", "cat", "dog", "]");
       docs[3] = BCON_NEW ("x", BCON_DOUBLE (3.0), "tags", "[", "]");

       for (i = 0; i < ndocs; i++) {
          mongoc_bulk_operation_insert (bulk, docs[i]);
          bson_destroy (docs[i]);
          docs[i] = NULL;
       }

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

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

       mongoc_bulk_operation_destroy (bulk);
       return ret;
    }

    /* A helper which we'll use a lot later on */
    void
    print_res (const bson_t *reply)
    {
       BSON_ASSERT (reply);
       char *str = bson_as_canonical_extended_json (reply, NULL);
       printf ("%s\n", str);
       bson_free (str);
    }

EXPLAIN COMMAND

This is how to use the explain command in MongoDB 3.2+: explain.c.INDENT 0.0

    bool
    explain (mongoc_collection_t *collection)
    {
       bson_t *command;
       bson_t reply;
       bson_error_t error;
       bool res;

       command = BCON_NEW ("explain",
                           "{",
                           "find",
                           BCON_UTF8 (COLLECTION_NAME),
                           "filter",
                           "{",
                           "x",
                           BCON_INT32 (1),
                           "}",
                           "}");
       res = mongoc_collection_command_simple (
          collection, command, NULL, &reply, &error);
       if (!res) {
          fprintf (stderr, "Error with explain: %s\n", error.message);
          goto cleanup;
       }

       /* Do something with the reply */
       print_res (&reply);

    cleanup:
       bson_destroy (&reply);
       bson_destroy (command);
       return res;
    }

COPYDB COMMAND

This example requires two instances of mongo to be running.

Here's how to use the copydb command to copy a database from another instance of MongoDB: copydb.c.INDENT 0.0

    bool
    copydb (mongoc_client_t *client, const char *other_host_and_port)
    {
       mongoc_database_t *admindb;
       bson_t *command;
       bson_t reply;
       bson_error_t error;
       bool res;

       BSON_ASSERT (other_host_and_port);
       /* Must do this from the admin db */
       admindb = mongoc_client_get_database (client, "admin");

       command = BCON_NEW ("copydb",
                           BCON_INT32 (1),
                           "fromdb",
                           BCON_UTF8 ("test"),
                           "todb",
                           BCON_UTF8 ("test2"),

                           /* If you want from a different host */
                           "fromhost",
                           BCON_UTF8 (other_host_and_port));
       res =
          mongoc_database_command_simple (admindb, command, NULL, &reply, &error);
       if (!res) {
          fprintf (stderr, "Error with copydb: %s\n", error.message);
          goto cleanup;
       }

       /* Do something with the reply */
       print_res (&reply);

    cleanup:
       bson_destroy (&reply);
       bson_destroy (command);
       mongoc_database_destroy (admindb);

       return res;
    }

CLONECOLLECTION COMMAND

This example requires two instances of mongo to be running.

Here's an example of the cloneCollection command to clone a collection from another instance of MongoDB: clone-collection.c.INDENT 0.0

    bool
    clone_collection (mongoc_database_t *database, const char *other_host_and_port)
    {
       bson_t *command;
       bson_t reply;
       bson_error_t error;
       bool res;

       BSON_ASSERT (other_host_and_port);
       command = BCON_NEW ("cloneCollection",
                           BCON_UTF8 ("test.remoteThings"),
                           "from",
                           BCON_UTF8 (other_host_and_port),
                           "query",
                           "{",
                           "x",
                           BCON_INT32 (1),
                           "}");
       res =
          mongoc_database_command_simple (database, command, NULL, &reply, &error);
       if (!res) {
          fprintf (stderr, "Error with clone: %s\n", error.message);
          goto cleanup;
       }

       /* Do something with the reply */
       print_res (&reply);

    cleanup:
       bson_destroy (&reply);
       bson_destroy (command);

       return res;
    }

RUNNING THE EXAMPLES
common-operations.c.INDENT 0.0

    /*
     * Copyright 2016 MongoDB, Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

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

    const char *COLLECTION_NAME = "things";

    #include "../doc-common-insert.c"
    #include "explain.c"
    #include "copydb.c"
    #include "clone-collection.c"

    int
    main (int argc, char *argv[])
    {
       mongoc_database_t *database = NULL;
       mongoc_client_t *client = NULL;
       mongoc_collection_t *collection = NULL;
       char *host_and_port;
       int res = 0;
       char *other_host_and_port = NULL;

       if (argc < 2 || argc > 3) {
          fprintf (stderr,
                   "usage: %s MONGOD-1-CONNECTION-STRING "
                   "[MONGOD-2-HOST-NAME:MONGOD-2-PORT]\n",
                   argv[0]);
          fprintf (stderr,
                   "MONGOD-1-CONNECTION-STRING can be "
                   "of the following forms:\n");
          fprintf (stderr, "localhost\t\t\t\tlocal machine\n");
          fprintf (stderr, "localhost:27018\t\t\t\tlocal machine on port 27018\n");
          fprintf (stderr,
                   "mongodb://user:pass@localhost:27017\t"
                   "local machine on port 27017, and authenticate with username "
                   "user and password pass\n");
          return 1;
       }

       mongoc_init ();

       if (strncmp (argv[1], "mongodb://", 10) == 0) {
          host_and_port = bson_strdup (argv[1]);
       } else {
          host_and_port = bson_strdup_printf ("mongodb://%s", argv[1]);
       }
       other_host_and_port = argc > 2 ? argv[2] : NULL;

       client = mongoc_client_new (host_and_port);

       if (!client) {
          fprintf (stderr, "Invalid hostname or port: %s\n", host_and_port);
          res = 2;
          goto cleanup;
       }

       mongoc_client_set_error_api (client, 2);
       database = mongoc_client_get_database (client, "test");
       collection = mongoc_database_get_collection (database, COLLECTION_NAME);

       printf ("Inserting data\n");
       if (!insert_data (collection)) {
          res = 3;
          goto cleanup;
       }

       printf ("explain\n");
       if (!explain (collection)) {
          res = 4;
          goto cleanup;
       }

       if (other_host_and_port) {
          printf ("copydb\n");
          if (!copydb (client, other_host_and_port)) {
             res = 5;
             goto cleanup;
          }

          printf ("clone collection\n");
          if (!clone_collection (database, other_host_and_port)) {
             res = 6;
             goto cleanup;
          }
       }

    cleanup:
       if (collection) {
          mongoc_collection_destroy (collection);
       }

       if (database) {
          mongoc_database_destroy (database);
       }

       if (client) {
          mongoc_client_destroy (client);
       }

       bson_free (host_and_port);
       mongoc_cleanup ();
       return res;
    }

First launch two separate instances of mongod (must be done from separate shells):

        $ mongod

        $ mkdir /tmp/db2$ mongod --dbpath /tmp/db2 --port 27018 # second instance

Now compile and run the example program:

        $ cd examples/common_operations/$ gcc -Wall -o example common-operations.c $(pkg-config --cflags --libs libmongoc-1.0)$ ./example localhost:27017 localhost:27018
        Inserting data
        explain
        {
           "executionStats" : {
              "allPlansExecution" : [],
              "executionStages" : {
                 "advanced" : 19,
                 "direction" : "forward" ,
                 "docsExamined" : 76,
                 "executionTimeMillisEstimate" : 0,
                 "filter" : {
                    "x" : {
                       "$eq" : 1
                    }
                 },
                 "invalidates" : 0,
                 "isEOF" : 1,
                 "nReturned" : 19,
                 "needTime" : 58,
                 "needYield" : 0,
                 "restoreState" : 0,
                 "saveState" : 0,
                 "stage" : "COLLSCAN" ,
                 "works" : 78
              },
              "executionSuccess" : true,
              "executionTimeMillis" : 0,
              "nReturned" : 19,
              "totalDocsExamined" : 76,
              "totalKeysExamined" : 0
           },
           "ok" : 1,
           "queryPlanner" : {
              "indexFilterSet" : false,
              "namespace" : "test.things",
              "parsedQuery" : {
                 "x" : {
                    "$eq" : 1
                 }
              },
              "plannerVersion" : 1,
              "rejectedPlans" : [],
              "winningPlan" : {
                 "direction" : "forward" ,
                 "filter" : {
                    "x" : {
                       "$eq" : 1
                    }
                 },
                 "stage" : "COLLSCAN"
              }
           },
           "serverInfo" : {
              "gitVersion" : "05552b562c7a0b3143a729aaa0838e558dc49b25" ,
              "host" : "MacBook-Pro-57.local",
              "port" : 27017,
              "version" : "3.2.6"
           }
        }
        copydb
        { "ok" : 1 }
        clone collection
        { "ok" : 1 }

AUTHOR
MongoDB, Inc

COPYRIGHT
2018, MongoDB, Inc