Tutorial for mongocxx

Prerequisites

  • A mongod instance running on localhost on port 27017.

  • The mongocxx Driver. See Installation for mongocxx.

  • The following statements at the top of your source file:

#include <cstdint>
#include <iostream>
#include <vector>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>

using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;

Compiling

The mongocxx driver’s installation process will install a libmongocxx.pc file for use with pkg-config.

To compile a program, run the following command:

c++ --std=c++11 <input>.cpp $(pkg-config --cflags --libs libmongocxx)

If you don’t have pkg-config available, you will need to set include and library flags manually on the command line or in your IDE. For example, if libmongoc and mongocxx are installed in /usr/local, then the compilation line in above expands to this:

c++ --std=c++11 <input>.cpp
  -I/usr/local/include/mongocxx/v_noabi -I/usr/local/include/libmongoc-1.0 \
  -I/usr/local/include/bsoncxx/v_noabi -I/usr/local/include/libbson-1.0 \
  -L/usr/local/lib -lmongocxx -lbsoncxx

Make a Connection

IMPORTANT: Before making any connections, you need to create one and only one instance of mongocxx::instance. This instance must exist for the entirety of your program.

To connect to a running MongoDB instance, use the mongocxx::client class.

You must specify the host to connect to using a mongocxx::uri instance containing a MongoDB URI, and pass that into the mongocxx::client constructor.

The default mongocxx::uri constructor will connect to a server running on localhost on port 27017:

mongocxx::instance instance{}; // This should be done only once.
mongocxx::client client{mongocxx::uri{}};

This is equivalent to the following:

mongocxx::instance instance{}; // This should be done only once.
mongocxx::uri uri("mongodb://localhost:27017");
mongocxx::client client(uri);

Access a Database

Once you have a mongocxx::client instance connected to a MongoDB deployment, use either the database() method or operator[] to obtain a mongocxx::database instance.

If the database you request does not exist, MongoDB creates it when you first store data.

The following example accesses the mydb database:

mongocxx::database db = client["mydb"];

Access a Collection

Once you have a mongocxx::database instance, use either the collection() method or operator[] to obtain a mongocxx::collection instance.

If the collection you request does not exist, MongoDB creates it when you first store data.

For example, using the db instance created in the previous section, the following statement accesses the collection named test in the mydb database:

mongocxx::collection coll = db["test"];

Create a Document

To create a document using the C++ driver, use one of the two available builder interfaces:

Stream builder: bsoncxx::builder::stream A document builder using the streaming operators that works well for literal document construction.

Basic builder: bsoncxx::builder::basic A more conventional document builder that involves calling methods on a builder instance.

This guide only briefly describes the stream builder.

For example, consider the following JSON document:

{
   "name" : "MongoDB",
   "type" : "database",
   "count" : 1,
   "versions": [ "v3.2", "v3.0", "v2.6" ],
   "info" : {
               "x" : 203,
               "y" : 102
            }
}

Using the stream builder interface, you can construct this document as follows:

auto builder = bsoncxx::builder::stream::document{};
bsoncxx::document::value doc_value = builder
  << "name" << "MongoDB"
  << "type" << "database"
  << "count" << 1
  << "versions" << bsoncxx::builder::stream::open_array
    << "v3.2" << "v3.0" << "v2.6"
  << close_array
  << "info" << bsoncxx::builder::stream::open_document
    << "x" << 203
    << "y" << 102
  << bsoncxx::builder::stream::close_document
  << bsoncxx::builder::stream::finalize;

Use bsoncxx::builder::stream::finalize to obtain a bsoncxx::document::value instance.

This bsoncxx::document::value type is a read-only object owning its own memory. To use it, you must obtain a bsoncxx::document::view using the view() method:

bsoncxx::document::view view = doc_value.view();

You can access fields within this document view using operator[], which will return a bsoncxx::document::element instance. For example, the following will extract the name field whose value is a string:

bsoncxx::document::element element = view["name"];
if(element.type() != bsoncxx::type::k_utf8) {
  // Error
}
std::string name = element.get_utf8().value.to_string();

If the value in the name field is not a string and you do not include a type guard as seen in the preceding example, this code will throw an instance of bsoncxx::exception.

Insert Documents

Insert One Document

To insert a single document into the collection, use a mongocxx::collection instance’s insert_one() method:

bsoncxx::stdx::optional<mongocxx::result::insert_one> result =
 restaurants.insert_one(doc);

If you do not specify a top-level _id field in the document, MongoDB automatically adds an _id field to the inserted document.

You can obtain this value using the inserted_id() method of the returned mongocxx::result::insert_one instance.

Insert Multiple Documents

To insert multiple documents to the collection, use a mongocxx::collection instance’s insert_many() method, which takes a list of documents to insert.

The following example will add multiple documents of the form:

{ "i" : value }

Create the documents in a loop and add to the documents list:

std::vector<bsoncxx::document::value> documents;
for(int i = 0; i < 100; i++) {
    documents.push_back(
      bsoncxx::builder::stream::document{} << "i" << i << finalize);
}

To insert these documents to the collection, pass the list of documents to the insert_many() method.

collection.insert_many(documents);

If you do not specify a top-level _id field in each document, MongoDB automatically adds a _id field to the inserted documents.

You can obtain this value using the inserted_ids() method of the returned mongocxx::result::insert_many instance.

Query the Collection

To query the collection, use the collection’s find() and find_one methods.

find() will return an instance of mongocxx::cursor, while find_one() will return an instance of std::optional<bsoncxx::document::value>

You can call either method without any arguments to query all documents in a collection, or pass a filter to query for documents that match the filter criteria.

Find a Single Document in a Collection

To return a single document in the collection, use the find_one() method without any parameters.

bsoncxx::stdx::optional<bsoncxx::document::value> maybe_result =
  collection.find_one(document{} << finalize);
if(maybe_result) {
  // Do something with *maybe_result;
}

Find All Documents in a Collection

mongocxx::cursor cursor = collection.find(document{} << finalize);
for(auto doc : cursor) {
  std::cout << bsoncxx::to_json(doc) << "\n";
}

Specify a Query Filter

Get A Single Document That Matches a Filter

To find the first document where the field i has the value 71, pass the document {"i": 71} to specify the equality condition:

bsoncxx::stdx::optional<bsoncxx::document::value> maybe_result =
  collection.find_one(document{} << "i" << 71 << finalize);
if(maybe_result) {
  std::cout << bsoncxx::to_json(*maybe_result) << "\n";
}

The example prints one document:

{ "_id" : { "$oid" : "5755e19b38c96f1fb25667a8" },  "i" : 71 }

The _id element has been added automatically by MongoDB to your document and your value will differ from that shown. MongoDB reserves field names that start with an underscore (_) and the dollar sign ($) for internal use.

Get All Documents That Match a Filter

The following example returns and prints all documents where 50 < "i" <= 100:

mongocxx::cursor cursor = collection.find(
  document{} << "i" << open_document <<
    "$gt" << 50 <<
    "$lte" << 100
  << close_document << finalize);
for(auto doc : cursor) {
  std::cout << bsoncxx::to_json(doc) << "\n";
}

Update Documents

To update documents in a collection, you can use the collection’s update_one() and update_many() methods.

The update methods return an instance of std::optional<mongocxx::result::update>, which provides information about the operation including the number of documents modified by the update.

Update a Single Document

To update at most one document, use the update_one() method.

The following example updates the first document that matches the filter { "i": 10 } and sets the value of i to 110:

collection.update_one(document{} << "i" << 10 << finalize,
                      document{} << "$set" << open_document <<
                        "i" << 110 << close_document << finalize);

Update Multiple Documents

To update all documents matching a filter, use the update_many() method.

The following example increments the value of i by 100 where i is less than 100:

bsoncxx::stdx::optional<mongocxx::result::update> result =
 collection.update_many(
  document{} << "i" << open_document <<
    "$lt" << 100 << close_document << finalize,
  document{} << "$inc" << open_document <<
    "i" << 100 << close_document << finalize);

if(result) {
  std::cout << result->modified_count() << "\n";
}

Delete Documents

To delete documents from a collection, you can use a collection’s delete_one() and delete_many() methods.

The delete methods return an instance of std::optional<mongocxx::result::delete>, which contains the number of documents deleted.

Delete a Single Document

To delete at most a single document that matches a filter, use the delete_one() method.

For example, to delete a document that matches the filter { "i": 110 }:

collection.delete_one(document{} << "i" << 110 << finalize);

Delete All Documents That Match a Filter

To delete all documents matching a filter, use a collection’s delete_many() method.

The following example deletes all documents where i is greater or equal to 100:

bsoncxx::stdx::optional<mongocxx::result::delete_result> result =
 collection.delete_many(
  document{} << "i" << open_document <<
    "$gte" << 100 << close_document << finalize);

if(result) {
  std::cout << result->deleted_count() << "\n";
}

Create Indexes

To create an index on a field or set of fields, pass an index specification document to the create_index() method of a mongocxx::collection instance. An index key specification document contains the fields to index and the index type for each field:

{ "index1": "<type>", "index2": <type> }
  • For an ascending index type, specify 1 for <type>.
  • For a descending index type, specify -1 for <type>.

The following example creates an ascending index on the i field:

auto index_specification = document{} << "i" << 1 << finalize;
collection.create_index(std::move(index_specification));