Loading...
Searching...
No Matches
Collections

How to obtain and use collections.

# Obtain a Collection

void example(mongocxx::database db) {
mongocxx::collection coll = db["coll"];
EXPECT(coll);
EXPECT(coll.name() == "coll");
EXPECT(db.collection("coll").name() == "coll");
}

# Collection Operations

## Drop a Collection

void example(mongocxx::database db) {
mongocxx::collection coll = db["coll"];
EXPECT(db.has_collection("coll"));
coll.drop();
EXPECT(!db.has_collection("coll"));
}

## Rename a Collection

void example(mongocxx::database db) {
mongocxx::collection coll = db["old"];
EXPECT(db.has_collection("old"));
EXPECT(!db.has_collection("new"));
EXPECT(coll.name() == "old");
coll.rename("new");
EXPECT(coll.name() == "new");
EXPECT(!db.has_collection("old"));
EXPECT(db.has_collection("new"));
}

## Set a Read Concern

void example(mongocxx::collection coll) {
using rc_level = mongocxx::read_concern::level;
// Default.
{
mongocxx::read_concern rc = coll.read_concern();
EXPECT(rc.acknowledge_level() == rc_level::k_server_default);
}
// Explicit.
{
mongocxx::read_concern rc;
rc.acknowledge_level(rc_level::k_majority);
// ... other read concern options.
coll.read_concern(rc);
EXPECT(coll.read_concern() == rc);
EXPECT(coll.read_concern().acknowledge_level() == rc_level::k_majority);
}
}

## Set a Write Concern

void example(mongocxx::collection coll) {
using wc_level = mongocxx::write_concern::level;
// Default.
{
mongocxx::write_concern wc = coll.write_concern();
EXPECT(wc.acknowledge_level() == wc_level::k_default);
EXPECT(wc.timeout() == std::chrono::milliseconds(0));
}
// Explicit.
{
mongocxx::write_concern wc;
wc.majority(std::chrono::milliseconds(5000));
// ... other write concern options.
coll.write_concern(wc);
EXPECT(coll.write_concern() == wc);
EXPECT(coll.write_concern().acknowledge_level() == wc_level::k_majority);
EXPECT(coll.write_concern().timeout() == std::chrono::seconds(5));
}
}

## Set a Read Preference

void example(mongocxx::collection coll) {
// Default.
{
mongocxx::read_preference rp;
EXPECT(coll.read_preference() == rp);
EXPECT(coll.read_preference().mode() == mongocxx::read_preference::read_mode::k_primary);
}
// Explicit.
{
mongocxx::read_preference rp;
rp.mode(mongocxx::read_preference::read_mode::k_secondary);
// ... other read preference options.
coll.read_preference(rp);
EXPECT(coll.read_preference() == rp);
}
}

# Index Operations

## On a Collection

### List Indexes

void example(mongocxx::collection coll) {
for (bsoncxx::document::view doc : coll.list_indexes()) {
EXPECT(doc["name"]);
EXPECT(doc["name"].type() == bsoncxx::type::k_string);
EXPECT(doc["key"]);
EXPECT(doc["key"].type() == bsoncxx::type::k_document);
}
}

### Create an Index

void example(mongocxx::collection coll) {
bsoncxx::document::value result = coll.create_index(bsoncxx::from_json(R"({"key": 1})"));
EXPECT(result["name"]);
EXPECT(result["name"].get_string().value == "key_1");
}

### Create an Index With Options

void example(mongocxx::collection coll) {
// Index options.
{
auto opts = bsoncxx::from_json(R"({"name": "custom_name", "unique": true})");
// ... other index options.
bsoncxx::document::value result = coll.create_index(bsoncxx::from_json(R"({"key_a": 1})"), opts.view());
EXPECT(result["name"]);
EXPECT(result["name"].get_string().value == "custom_name");
}
// Create index options.
{
auto opts = bsoncxx::builder::basic::make_document();
mongocxx::options::index_view create_opts;
// ... set create index options.
bsoncxx::document::value result = coll.create_index(bsoncxx::from_json(R"({"key_b": 1})"), opts.view());
EXPECT(result["name"]);
EXPECT(result["name"].get_string().value == "key_b_1");
}
}

## With an Index View

### Obtain an Index View

void example(mongocxx::collection coll) {
mongocxx::index_view indexes = coll.indexes();
for (bsoncxx::document::view doc : indexes.list()) {
EXPECT(doc["key"]);
EXPECT(doc["name"]);
}
}

### List Indexes

void example(mongocxx::index_view indexes) {
for (bsoncxx::document::view doc : indexes.list()) {
EXPECT(doc["name"]);
EXPECT(doc["name"].type() == bsoncxx::type::k_string);
EXPECT(doc["key"]);
EXPECT(doc["key"].type() == bsoncxx::type::k_document);
}
}

### Create an Index

void example(mongocxx::index_view indexes) {
// Basic usage.
{
auto result_opt = indexes.create_one(bsoncxx::from_json(R"({"x": 1})"));
EXPECT(result_opt);
EXPECT(result_opt->compare("x_1") == 0);
}
// Index model.
{
auto result_opt = indexes.create_one(mongocxx::index_model{bsoncxx::from_json(R"({"y": 1})")});
EXPECT(result_opt);
EXPECT(result_opt->compare("y_1") == 0);
}
}

### Create an Index With Options

void example(mongocxx::index_view indexes) {
// Index options.
{
auto opts = bsoncxx::from_json(R"({"name": "one"})");
// ... other index options.
auto result_opt = indexes.create_one(bsoncxx::from_json(R"({"key_a": 1})"), opts.view());
EXPECT(result_opt);
EXPECT(result_opt->compare("one") == 0);
}
// Index model.
{
auto result_opt = indexes.create_one(
mongocxx::index_model{
bsoncxx::from_json(R"({"y": 1})"),
bsoncxx::from_json(R"({"name": "two"})"),
});
EXPECT(result_opt);
EXPECT(result_opt->compare("two") == 0);
}
// Create index options.
{
auto opts = bsoncxx::builder::basic::make_document();
mongocxx::options::index_view create_opts;
// ... set create index options.
auto result_opt = indexes.create_one(bsoncxx::from_json(R"({"z": 1})"), opts.view());
EXPECT(result_opt);
EXPECT(result_opt->compare("z_1") == 0);
}
}

### Create Multiple Indexes

void example(mongocxx::index_view indexes) {
std::vector<mongocxx::index_model> models;
models.emplace_back(bsoncxx::from_json(R"({"x": 1})"));
models.emplace_back(bsoncxx::from_json(R"({"y": 1})"));
auto result = indexes.create_many(models);
// SERVER-78611
if (result["raw"]) {
result = result["raw"].get_document().value.begin()->get_document().value;
}
EXPECT(result["ok"]);
EXPECT(result["ok"].get_double().value == 1.0);
EXPECT(result["numIndexesBefore"]);
EXPECT(result["numIndexesBefore"].get_int32().value == 1); // _id_
EXPECT(result["numIndexesAfter"]);
EXPECT(result["numIndexesAfter"].get_int32().value == 3); // _id_, x_1, y_1
}

### Drop an Index

// [
// {
// "key": { "_id": 1 },
// "name": "_id_"
// {
// "key": { "x": 1 },
// "name": "x_1"
// },
// {
// "key": { "y": 1 },
// "name": "custom_name"
// }
// ]
void example(mongocxx::index_view indexes) {
auto count_indexes = [&indexes] {
auto cursor = indexes.list();
return std::distance(cursor.begin(), cursor.end());
};
EXPECT(count_indexes() == 3); // _id_, x_1, custom_name
indexes.drop_one("custom_name");
EXPECT(count_indexes() == 2); // _id_, x_1
indexes.drop_one(bsoncxx::from_json(R"({"x": 1})"));
EXPECT(count_indexes() == 1); // _id_
}

### Drop All Indexes

// [
// {
// "key": { "_id": 1 },
// "name": "_id_"
// {
// "key": { "x": 1 },
// "name": "x_1"
// },
// {
// "key": { "y": 1 },
// "name": "custom_name"
// }
// ]
void example(mongocxx::index_view indexes) {
auto count_indexes = [&indexes] {
auto cursor = indexes.list();
return std::distance(cursor.begin(), cursor.end());
};
EXPECT(count_indexes() == 3); // _id_, x_1, custom_name
indexes.drop_all();
EXPECT(count_indexes() == 1); // _id_
}

# Document Operations

## Query the Number of Documents

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
{
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})")) == 3);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$gt": 1}})")) == 2);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$gt": 2}})")) == 1);
}
// With options.
{
mongocxx::options::count opts;
opts.limit(1);
// ... other count options.
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})"), opts) == 1);
}
}

## Estimate the Number of Documents

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
EXPECT(coll.estimated_document_count() == 3);
// With options.
{
mongocxx::options::estimated_document_count opts;
// ... set estimated count options.
EXPECT(coll.estimated_document_count(opts) == 3);
}
}

## Find a Document

// [
// {"x": 1, "found": false},
// {"x": 2, "found": true},
// {"x": 3, "found": false},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
{
auto filter = bsoncxx::from_json(R"({"found": true})");
auto result_opt = coll.find_one(filter.view());
EXPECT(result_opt);
bsoncxx::document::view doc = result_opt->view();
EXPECT(doc["_id"]);
EXPECT(doc["x"]);
EXPECT(doc["x"].get_int32().value == 2);
}
// With options.
{
mongocxx::options::find opts;
opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})"));
opts.sort(bsoncxx::from_json(R"({"x": 1})"));
// ... other find options.
auto result_opt = coll.find_one(bsoncxx::builder::basic::make_document(), opts);
EXPECT(result_opt);
EXPECT(*result_opt == bsoncxx::from_json(R"({"x": 1})"));
}
}

## Find Multiple Documents

// [
// {"x": 1, "found": true},
// {"x": 2, "found": false},
// {"x": 3, "found": true},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
{
auto filter = bsoncxx::from_json(R"({"found": true})");
mongocxx::cursor cursor = coll.find(filter.view());
int count = 0;
for (bsoncxx::document::view doc : cursor) {
EXPECT(doc["_id"]);
EXPECT(doc["x"]);
EXPECT(doc["x"].get_int32().value != 2);
++count;
}
EXPECT(count == 2);
}
// With options.
{
mongocxx::options::find opts;
opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})"));
opts.sort(bsoncxx::from_json(R"({"x": 1})"));
// ... other find options.
mongocxx::cursor cursor = coll.find(bsoncxx::builder::basic::make_document(), opts);
std::vector<bsoncxx::document::value> docs{cursor.begin(), cursor.end()};
EXPECT(docs.size() == 3u);
EXPECT(docs[0] == bsoncxx::from_json(R"({"x": 1})"));
EXPECT(docs[1] == bsoncxx::from_json(R"({"x": 2})"));
EXPECT(docs[2] == bsoncxx::from_json(R"({"x": 3})"));
}
}

## Delete a Document

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto x3 = bsoncxx::from_json(R"({"x": 3})");
// Basic usage.
{
EXPECT(coll.count_documents(x1.view()) == 1);
auto result_opt = coll.delete_one(x1.view());
EXPECT(result_opt);
mongocxx::result::delete_result& result = *result_opt;
EXPECT(result.deleted_count() == 1);
EXPECT(result.result().deleted_count() == 1);
EXPECT(coll.count_documents(x1.view()) == 0);
}
// With options.
{
EXPECT(coll.count_documents(x2.view()) == 1);
mongocxx::options::delete_options opts;
// ... set delete options.
EXPECT(coll.delete_one(x2.view(), opts));
EXPECT(coll.count_documents(x2.view()) == 0);
}
EXPECT(coll.count_documents(x3.view()) == 1);
}

## Delete Many Documents

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto x3 = bsoncxx::from_json(R"({"x": 3})");
// Basic usage.
{
EXPECT(coll.count_documents(x1.view()) == 1);
EXPECT(coll.count_documents(x2.view()) == 1);
EXPECT(coll.count_documents(x3.view()) == 1);
auto result_opt = coll.delete_many(bsoncxx::from_json(R"({"x": {"$gt": 1}})"));
EXPECT(result_opt);
mongocxx::result::delete_result& result = *result_opt;
EXPECT(result.deleted_count() == 2);
EXPECT(result.result().deleted_count() == 2);
EXPECT(coll.count_documents(x1.view()) == 1);
EXPECT(coll.count_documents(x2.view()) == 0);
EXPECT(coll.count_documents(x3.view()) == 0);
}
// With options.
{
EXPECT(coll.count_documents(x1.view()) == 1);
mongocxx::options::delete_options opts;
// ... set delete options.
EXPECT(coll.delete_many(bsoncxx::from_json(R"({"x": {"$exists": 1}})"), opts));
EXPECT(coll.count_documents(x1.view()) == 0);
}
}

## Insert a Document

void example(mongocxx::collection coll) {
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
// Basic usage.
{
EXPECT(coll.count_documents(x1.view()) == 0);
auto result_opt = coll.insert_one(x1.view());
EXPECT(result_opt);
mongocxx::result::insert_one& result = *result_opt;
EXPECT(result.result().inserted_count() == 1);
EXPECT(coll.count_documents(x1.view()) == 1);
}
// With options.
{
EXPECT(coll.count_documents(x2.view()) == 0);
mongocxx::options::insert opts;
// ... set insert options.
EXPECT(coll.insert_one(x2.view(), opts));
EXPECT(coll.count_documents(x2.view()) == 1);
}
}

## Insert Many Documents

void example(mongocxx::collection coll) {
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto y1 = bsoncxx::from_json(R"({"y": 1})");
auto y2 = bsoncxx::from_json(R"({"y": 2})");
auto z1 = bsoncxx::from_json(R"({"z": 1})");
auto z2 = bsoncxx::from_json(R"({"z": 2})");
// Basic usage.
{
std::vector<bsoncxx::document::view> docs = {x1.view(), x2.view()};
auto result_opt = coll.insert_many(docs);
EXPECT(result_opt);
mongocxx::result::insert_many& result = *result_opt;
EXPECT(result.inserted_count() == 2);
EXPECT(result.result().inserted_count() == 2);
}
// Iterators.
{
bsoncxx::document::view docs[] = {y1.view(), y2.view()};
auto result_opt = coll.insert_many(std::begin(docs), std::end(docs));
EXPECT(result_opt);
mongocxx::result::insert_many& result = *result_opt;
EXPECT(result.inserted_count() == 2);
EXPECT(result.result().inserted_count() == 2);
}
// With options.
{
std::array<bsoncxx::document::view, 2> docs = {z1.view(), z2.view()};
mongocxx::options::insert opts;
// ... set insert options.
EXPECT(coll.insert_many(docs, opts));
}
}

## Replace a Document

// [
// {"x": 1, "replaced": false},
// {"x": 2, "replaced": false},
// {"x": 3, "replaced": false},
// ]
void example(mongocxx::collection coll) {
auto is_original = bsoncxx::from_json(R"({"replaced": false})");
auto is_replaced = bsoncxx::from_json(R"({"replaced": true})");
auto x0 = bsoncxx::from_json(R"({"x": 0, "replaced": true})");
// Basic usage.
{
EXPECT(coll.count_documents(x0.view()) == 0);
auto filter = bsoncxx::from_json(R"({"x": 2})");
auto result_opt = coll.replace_one(filter.view(), x0.view());
EXPECT(result_opt);
mongocxx::result::replace_one& result = *result_opt;
EXPECT(result.matched_count() == 1);
EXPECT(result.modified_count() == 1);
EXPECT(result.result().matched_count() == 1);
EXPECT(result.result().modified_count() == 1);
EXPECT(coll.count_documents(x0.view()) == 1);
}
// With options.
{
EXPECT(coll.count_documents(is_original.view()) == 2);
EXPECT(coll.count_documents(is_replaced.view()) == 1);
mongocxx::options::replace opts;
opts.upsert(true);
// ... other replace options.
auto filter = bsoncxx::from_json(R"({"replaced": false})");
EXPECT(coll.replace_one(filter.view(), x0.view(), opts));
EXPECT(coll.count_documents(is_original.view()) == 1);
EXPECT(coll.count_documents(is_replaced.view()) == 2);
EXPECT(coll.replace_one(filter.view(), x0.view(), opts));
EXPECT(coll.count_documents(is_original.view()) == 0);
EXPECT(coll.count_documents(is_replaced.view()) == 3);
EXPECT(coll.replace_one(filter.view(), x0.view(), opts));
EXPECT(coll.count_documents(is_original.view()) == 0);
EXPECT(coll.count_documents(is_replaced.view()) == 4);
}
}

## Update a Document

// [
// {"x": 1, "updated": false},
// {"x": 2, "updated": false},
// {"x": 3, "updated": false},
// ]
void example(mongocxx::collection coll) {
auto updated = bsoncxx::from_json(R"({"updated": true})");
// Basic usage.
{
EXPECT(coll.count_documents(updated.view()) == 0);
auto filter = bsoncxx::from_json(R"({"x": 2})");
auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})");
auto result_opt = coll.update_one(filter.view(), update.view());
EXPECT(result_opt);
mongocxx::result::update& result = *result_opt;
EXPECT(result.matched_count() == 1);
EXPECT(result.modified_count() == 1);
EXPECT(result.result().matched_count() == 1);
EXPECT(result.result().modified_count() == 1);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 2, "updated": true})")) == 1);
EXPECT(coll.count_documents(updated.view()) == 1);
}
// With options.
{
EXPECT(coll.count_documents(updated.view()) == 1);
auto x4 = bsoncxx::from_json(R"({"x": 4, "updated": true})");
EXPECT(coll.count_documents(x4.view()) == 0);
mongocxx::options::update opts;
opts.upsert(true);
// ... other update options.
EXPECT(coll.update_one(
bsoncxx::from_json(R"({"x": 4})"), bsoncxx::from_json(R"({"$set": {"updated": true}})"), opts));
EXPECT(coll.count_documents(x4.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 2);
}
}

## Update Multiple Documents

// [
// {"x": 1, "updated": false},
// {"x": 2, "updated": false},
// {"x": 3, "updated": false},
// ]
void example(mongocxx::collection coll) {
auto original = bsoncxx::from_json(R"({"updated": false})");
auto updated = bsoncxx::from_json(R"({"updated": true})");
auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})");
// Basic usage.
{
EXPECT(coll.count_documents(updated.view()) == 0);
auto filter = bsoncxx::from_json(R"({"x": {"$gt": 1}})");
auto result_opt = coll.update_many(filter.view(), update.view());
EXPECT(result_opt);
mongocxx::result::update& result = *result_opt;
EXPECT(result.matched_count() == 2);
EXPECT(result.modified_count() == 2);
EXPECT(result.result().matched_count() == 2);
EXPECT(result.result().modified_count() == 2);
EXPECT(coll.count_documents(updated.view()) == 2);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1, "updated": false})")) == 1);
}
// With options.
{
EXPECT(coll.count_documents(original.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 2);
mongocxx::options::update opts;
opts.upsert(true);
// ... other update options.
EXPECT(coll.update_many(original.view(), update.view(), opts));
EXPECT(coll.count_documents(original.view()) == 0);
EXPECT(coll.count_documents(updated.view()) == 3);
EXPECT(coll.update_many(original.view(), update.view(), opts));
EXPECT(coll.count_documents(original.view()) == 0);
EXPECT(coll.count_documents(updated.view()) == 4);
}
}

## Find and Delete a Document

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
auto has_field_x = bsoncxx::from_json(R"({"x": {"$exists": true}})");
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto x3 = bsoncxx::from_json(R"({"x": 3})");
// Basic usage.
{
EXPECT(coll.count_documents(has_field_x.view()) == 3);
auto result_opt = coll.find_one_and_delete(x2.view());
EXPECT(result_opt);
bsoncxx::document::view doc = result_opt->view();
EXPECT(doc["_id"]);
EXPECT(doc["x"]);
EXPECT(doc["x"].get_int32().value == 2);
EXPECT(coll.count_documents(has_field_x.view()) == 2);
}
// With options.
{
EXPECT(coll.count_documents(has_field_x.view()) == 2);
mongocxx::options::find_one_and_delete opts;
opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})"));
// ... other findOneAndDelete options.
auto result_opt = coll.find_one_and_delete(x3.view(), opts);
EXPECT(result_opt);
EXPECT(*result_opt == x3);
EXPECT(coll.count_documents(has_field_x.view()) == 1);
}
EXPECT(coll.count_documents(x1.view()) == 1);
}

## Find and Replace a Document

// [
// {"x": 1},
// {"x": 2},
// {"x": 3},
// ]
void example(mongocxx::collection coll) {
auto x0 = bsoncxx::from_json(R"({"x": 0})");
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto x3 = bsoncxx::from_json(R"({"x": 3})");
// Basic usage.
{
EXPECT(coll.count_documents(x0.view()) == 0);
auto result_opt = coll.find_one_and_replace(x2.view(), x0.view());
EXPECT(result_opt);
bsoncxx::document::view doc = result_opt->view();
EXPECT(doc["_id"]);
EXPECT(doc["x"]);
EXPECT(doc["x"].get_int32().value == 2);
EXPECT(coll.count_documents(x0.view()) == 1);
}
// With options.
{
EXPECT(coll.count_documents(x0.view()) == 1);
mongocxx::options::find_one_and_replace opts;
opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})"));
// ... other findOneAndReplace options.
auto result_opt = coll.find_one_and_replace(x3.view(), x0.view(), opts);
EXPECT(result_opt);
EXPECT(*result_opt == x3);
EXPECT(coll.count_documents(x0.view()) == 2);
}
EXPECT(coll.count_documents(x1.view()) == 1);
}

## Find and Update a Document

// [
// {"x": 1, "updated": false},
// {"x": 2, "updated": false},
// {"x": 3, "updated": false},
// ]
void example(mongocxx::collection coll) {
auto updated = bsoncxx::from_json(R"({"updated": true})");
auto x1 = bsoncxx::from_json(R"({"x": 1})");
auto x2 = bsoncxx::from_json(R"({"x": 2})");
auto x3 = bsoncxx::from_json(R"({"x": 3})");
auto update = bsoncxx::from_json(R"({"$set": {"updated": true}})");
// Basic usage.
{
EXPECT(coll.count_documents(x2.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 0);
auto result_opt = coll.find_one_and_update(x2.view(), update.view());
EXPECT(result_opt);
bsoncxx::document::view doc = result_opt->view();
EXPECT(doc["_id"]);
EXPECT(doc["x"]);
EXPECT(doc["x"].get_int32().value == 2);
EXPECT(coll.count_documents(x2.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 1);
}
// With options.
{
EXPECT(coll.count_documents(x3.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 1);
mongocxx::options::find_one_and_update opts;
opts.projection(bsoncxx::from_json(R"({"_id": 0, "x": 1})"));
// ... other findOneAndReplace options.
auto result_opt = coll.find_one_and_update(x3.view(), update.view(), opts);
EXPECT(result_opt);
EXPECT(*result_opt == x3);
EXPECT(coll.count_documents(x3.view()) == 1);
EXPECT(coll.count_documents(updated.view()) == 2);
}
EXPECT(coll.count_documents(x1.view()) == 1);
}

## Find Distinct Values

// [
// {"x": 1, "flag": 1},
// {"x": 2, "flag": 1},
// {"x": 3, "flag": 0},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
{
mongocxx::cursor cursor = coll.distinct("x", bsoncxx::from_json(R"({"flag": 1})"));
std::vector<bsoncxx::document::value> docs{cursor.begin(), cursor.end()};
EXPECT(docs.size() == 1u);
auto doc = docs[0].view();
EXPECT(doc["values"]);
EXPECT(doc["values"].type() == bsoncxx::type::k_array);
auto arr = doc["values"].get_array().value;
EXPECT(std::distance(arr.begin(), arr.end()) == 2);
EXPECT(arr[0].get_int32().value == 1);
EXPECT(arr[1].get_int32().value == 2);
}
// With options.
{
mongocxx::options::distinct opts;
// ... set distinct options.
mongocxx::cursor cursor = coll.distinct("x", bsoncxx::from_json(R"({"flag": 1})"), opts);
EXPECT(std::distance(cursor.begin(), cursor.end()) == 1);
}
}

## Execute a Single Bulk Write Operation

void example(mongocxx::collection coll) {
{
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1})")) == 0);
mongocxx::model::insert_one insert{bsoncxx::from_json(R"({"x": 1})")};
auto result_opt = coll.write(insert);
EXPECT(result_opt);
EXPECT(result_opt->inserted_count() == 1);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 1})")) == 1);
}
{
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"y": 1})")) == 0);
mongocxx::options::bulk_write opts;
opts.ordered(true);
// ... other bulk write options.
EXPECT(coll.write(mongocxx::model::insert_one{bsoncxx::from_json(R"({"y": 1})")}, opts));
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"y": 1})")) == 1);
}
}

## Execute Multiple Bulk Write Operations

void example(mongocxx::collection coll) {
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": {"$exists": 1}})")) == 0);
mongocxx::model::insert_one insert{bsoncxx::from_json(R"({"x": 10})")};
mongocxx::model::update_one update{
bsoncxx::from_json(R"({"x": {"$exists": 1}})"), bsoncxx::from_json(R"({"$set": {"x": 20}})")};
mongocxx::bulk_write bulk_write = coll.create_bulk_write();
bulk_write.append(insert);
bulk_write.append(update);
// ... other bulk write operations.
auto result_opt = bulk_write.execute();
EXPECT(result_opt);
mongocxx::result::bulk_write& result = *result_opt;
EXPECT(result.inserted_count() == 1);
EXPECT(result.modified_count() == 1);
EXPECT(coll.count_documents(bsoncxx::from_json(R"({"x": 20})")) == 1);
}

## Execute an Aggregation Operation

// [
// {"x": 1},
// {"x": 2},
// ]
void example(mongocxx::collection coll) {
// Basic usage.
{
mongocxx::pipeline pipeline;
pipeline.match(bsoncxx::from_json(R"({"x": 1})"));
pipeline.sample(1);
// ... other pipeline stages.
mongocxx::cursor cursor = coll.aggregate(pipeline);
auto has_field_x = [](bsoncxx::document::view doc) -> bool { return doc.find("x") != doc.end(); };
EXPECT(std::count_if(cursor.begin(), cursor.end(), has_field_x) == 1);
}
// With options.
{
mongocxx::options::aggregate opts;
// ... set aggregate options.
mongocxx::cursor cursor = coll.aggregate(mongocxx::pipeline{}, opts);
EXPECT(std::distance(cursor.begin(), cursor.end()) == 2);
}
}

# Error Handling

## Invalid Collection

void example(mongocxx::collection coll) {
mongocxx::options::find_one_and_update opts;
opts.collation(bsoncxx::from_json(R"({"locale": "simple"})"));
{
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_unacknowledged);
opts.write_concern(wc);
}
auto empty = bsoncxx::builder::basic::make_document();
try {
auto name = coll.find_one_and_update(empty.view(), empty.view(), opts);
EXPECT(false && "should not reach this point");
} catch (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
}

## Invalid Parameter

void example(mongocxx::collection coll) {
mongocxx::options::find opts;
opts.max_await_time(std::chrono::milliseconds(-1));
try {
auto name = coll.find(bsoncxx::builder::basic::make_document(), opts);
EXPECT(false && "should not reach this point");
} catch (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
}

## Incompatible Options

void example(mongocxx::collection coll) {
mongocxx::options::find_one_and_update opts;
opts.collation(bsoncxx::from_json(R"({"locale": "simple"})"));
{
mongocxx::write_concern wc;
wc.acknowledge_level(mongocxx::write_concern::level::k_unacknowledged);
opts.write_concern(wc);
}
auto empty = bsoncxx::builder::basic::make_document();
try {
auto name = coll.find_one_and_update(empty.view(), empty.view(), opts);
EXPECT(false && "should not reach this point");
} catch (mongocxx::exception const& ex) {
EXPECT(ex.code() == mongocxx::error_code::k_invalid_parameter);
}
}