Tutorial
On this page
- Prerequisites
- Compiling
- Make a Connection
- Access a Database
- Access a Collection
- Create a Document
- Insert Documents
- Insert One Document
- Insert Multiple Documents
- Query the Collection
- Find a Single Document in a Collection
- Find All Documents in a Collection
- Print All Documents in a Collection
- Specify a Query Filter
- Update Documents
- Update a Single Document
- Update Multiple Documents
- Delete Documents
- Delete a Single Document
- Delete All Documents That Match a Filter
- Create Indexes
See the full code for this tutorial in tutorial.cpp.
Prerequisites
A mongod instance running on localhost on port 27017.
The mongocxx Driver. See Installation.
The following statements at the top of your source file:
using bsoncxx::builder::basic::kvp; using bsoncxx::builder::basic::make_array; using bsoncxx::builder::basic::make_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/bsoncxx/v_noabi \ -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::instance 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. For details regarding
supported URI options see the documentation for the version of libmongoc used
to build the C++ driver or for the latest libmongoc release.
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::instance
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:
auto 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:
auto collection = 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.
- Stream builder:
- Basic builder:
bsoncxx::builder::basic
- A more conventional document builder that involves calling methods ona builder instance.
- Basic builder:
This guide only briefly describes the basic builder.
For example, consider the following JSON document:
{ "name" : "MongoDB", "type" : "database", "count" : 1, "versions": [ "v6.0", "v5.0", "v4.4", "v4.2", "v4.0", "v3.6" ], "info" : { "x" : 203, "y" : 102 } }
Using the basic builder interface, you can construct this document as follows:
auto doc_value = make_document( kvp("name", "MongoDB"), kvp("type", "database"), kvp("count", 1), kvp("versions", make_array("v6.0", "v5.0", "v4.4", "v4.2", "v4.0", "v3.6")), kvp("info", make_document(kvp("x", 203), kvp("y", 102))) );
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:
auto doc_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:
auto element = doc_view["name"]; assert(element.type() == bsoncxx::type::k_string); auto name = element.get_string().value; // For C++ driver version < 3.7.0, use get_utf8() assert(0 == name.compare("MongoDB"));
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 to insert { "i": 0 }
:
auto insert_one_result = collection.insert_one(make_document(kvp("i", 0)));
insert_one_result
is an optional mongocxx::result::insert_one. In this
example, insert_one_result
is expected to be set. The default behavior for
write operations is to wait for a reply from the server. This may be overridden by setting an unacknowledged
mongocxx::write_concern.
assert(insert_one_result); // Acknowledged writes return results.
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.
auto doc_id = insert_one_result->inserted_id(); assert(doc_id.type() == bsoncxx::type::k_oid);
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 inserts the documents { "i": 1 }
and { "i": 2 }
.
Create the documents and add to the documents list:
std::vector<bsoncxx::document::value> documents; documents.push_back(make_document(kvp("i", 1))); documents.push_back(make_document(kvp("i", 2)));
To insert these documents to the collection, pass the list of documents to the insert_many()
method.
auto insert_many_result = collection.insert_many(documents); assert(insert_many_result); // Acknowledged writes return results.
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.
auto doc0_id = insert_many_result->inserted_ids().at(0); auto doc1_id = insert_many_result->inserted_ids().at(1); assert(doc0_id.type() == bsoncxx::type::k_oid); assert(doc1_id.type() == bsoncxx::type::k_oid);
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 >
. For more information, see
bsoncxx::document::value.
You can call either method with an empty document 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.
auto find_one_result = collection.find_one({}); if (find_one_result) { // Do something with *find_one_result } assert(find_one_result);
Find All Documents in a Collection
auto cursor_all = collection.find({}); for (auto doc : cursor_all) { // Do something with doc assert(doc["_id"].type() == bsoncxx::type::k_oid); }
Print All Documents in a Collection
The bsoncxx::to_json function converts a BSON document to a JSON string.
auto cursor_all = collection.find({}); std::cout << "collection " << collection.name() << " contains these documents:" << std::endl; for (auto doc : cursor_all) { std::cout << bsoncxx::to_json(doc, bsoncxx::ExtendedJsonMode::k_relaxed) << std::endl; } std::cout << std::endl;
The above example prints output resembling the following:
collection test contains these documents: { "_id" : { "$oid" : "6409edb48c37f371c70f03a1" }, "i" : 0 } { "_id" : { "$oid" : "6409edb48c37f371c70f03a2" }, "i" : 1 } { "_id" : { "$oid" : "6409edb48c37f371c70f03a3" }, "i" : 2 }
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.
Specify a Query Filter
Get A Single Document That Matches a Filter
To find the first document where the field i
has the value 0
,
pass the document {"i": 0}
to specify the equality condition:
auto find_one_filtered_result = collection.find_one(make_document(kvp("i", 0))); if (find_one_filtered_result) { // Do something with *find_one_filtered_result }
Get All Documents That Match a Filter
The following example gets all documents where 0 < "i" <= 2
:
auto cursor_filtered = collection.find(make_document(kvp("i", make_document(kvp("$gt", 0), kvp("$lte", 2))))); for (auto doc : cursor_filtered) { // Do something with doc assert(doc["_id"].type() == bsoncxx::type::k_oid); }
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. For more information,
see mongocxx::result::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": 0 }
and sets the value of foo
to bar
:
auto update_one_result = collection.update_one(make_document(kvp("i", 0)), make_document(kvp("$set", make_document(kvp("foo", "bar"))))); assert(update_one_result); // Acknowledged writes return results. assert(update_one_result->modified_count() == 1);
Update Multiple Documents
To update all documents matching a filter, use the update_many()
method.
The following example sets the value of foo
to buzz
where
i
is greater than 0
:
auto update_many_result = collection.update_many(make_document(kvp("i", make_document(kvp("$gt", 0)))), make_document(kvp("$set", make_document(kvp("foo", "buzz"))))); assert(update_many_result); // Acknowledged writes return results. assert(update_many_result->modified_count() == 2);
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.
For more information, see mongocxx::result::delete.
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": 0 }
:
auto delete_one_result = collection.delete_one(make_document(kvp("i", 0))); assert(delete_one_result); // Acknowledged writes return results. assert(delete_one_result->deleted_count() == 1);
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 than 0
:
auto delete_many_result = collection.delete_many(make_document(kvp("i", make_document(kvp("$gt", 0))))); assert(delete_many_result); // Acknowledged writes return results. assert(delete_many_result->deleted_count() == 2);
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 = make_document(kvp("i", 1)); collection.create_index(std::move(index_specification));