mongoc_common_task_examples man page

Common_Tasks — None 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:

/* 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 (collection, true, 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_json (reply, NULL);
   printf ("%s\n", str);
   bson_free (str);
}

Explain Command

This is how to use the explain command in MongoDB 3.2+:

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:

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:

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

/*
 * 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 }

Colophon

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

Info

2016‐10‐20 MongoDB C Driver