MongoDB C++ Driver mongocxx-4.0.0
Loading...
Searching...
No Matches
BSON Documents

Table of Contents

How to create and use BSON documents.

Create a Document

From a JSON String

Basic Example

void example() {
{
"a": 1,
"b": 2.0,
"c": "three"
}
)");
bsoncxx::document::view doc = owner.view();
EXPECT(doc["a"].get_int32().value == 1);
EXPECT(doc["b"].get_double().value == 2.0);
EXPECT(doc["c"].get_string().value == "three");
}

With Extended JSON

void example() {
{
"a": {"$numberInt": "1"},
"b": {"$numberLong": "2"},
"c": {"$numberDouble": "3"}
}
)");
bsoncxx::document::view doc = owner.view();
EXPECT(doc["a"].get_int32().value == 1);
EXPECT(doc["b"].get_int64().value == 2);
EXPECT(doc["c"].get_double().value == 3.0);
}

With a Sub-Document

void example() {
{
"v": {"key": "value"}
}
)");
bsoncxx::document::view v = doc["v"].get_document().value;
EXPECT(v == bsoncxx::from_json(R"({"key": "value"})"));
}

With a Sub-Array

void example() {
{
"v": [1, 2]
}
)");
bsoncxx::array::view sub = owner.view()["v"].get_array().value;
}

With a User-Defined Literal

void example() {
using namespace bsoncxx;
bsoncxx::document::value a = R"({"key": "value"})"_bson;
bsoncxx::document::value b = bsoncxx::from_json(R"({"key": "value"})");
EXPECT(a == b);
}

Using the Basic Builder

Basic Example

void example() {
builder.append(kvp("a", std::int32_t{1}), kvp("b", 2.0), kvp("c", "three"));
bsoncxx::document::value doc = builder.extract();
EXPECT(doc.view() == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

With make_document

void example() {
kvp("a", std::int32_t{1}), kvp("b", 2.0), kvp("c", "three"));
EXPECT(doc.view() == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

With concatenate

// a: {"a": 1}
// b: {"b": 2}
builder.append(bsoncxx::builder::concatenate(a));
builder.append(bsoncxx::builder::concatenate(b));
EXPECT(builder.view() == bsoncxx::from_json(R"({"a": 1, "b": 2})"));
}

With Multiple Appends

void example() {
builder.append(kvp("a", std::int32_t{1}));
builder.append(kvp("b", 2.0));
builder.append(kvp("c", "three"));
bsoncxx::document::value doc = builder.extract();
EXPECT(doc == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

To Create Multiple Documents

void example() {
builder.append(kvp("a", 1));
bsoncxx::document::value a = builder.extract();
builder.clear();
builder.append(kvp("b", 2));
bsoncxx::document::value b = builder.extract();
EXPECT(a.view() == bsoncxx::from_json(R"({"a": 1})"));
EXPECT(b.view() == bsoncxx::from_json(R"({"b": 2})"));
}

With a Value Type

void example() {
kvp("a", std::int32_t{1}), kvp("b", 2.0), kvp("c", "three"));
EXPECT(doc == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

With a BSON Type

void example() {
bsoncxx::builder::basic::make_document(kvp("a", a), kvp("b", b), kvp("c", c));
EXPECT(doc.view() == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

With a BSON Value

void example() {
std::int32_t{1},
2.0,
"three",
};
kvp("a", values[0]), kvp("b", values[1]), kvp("c", values[2]));
EXPECT(doc.view() == bsoncxx::from_json(R"({"a": 1, "b": 2.0, "c": "three"})"));
}

With a Sub-Document

void example() {
bsoncxx::document::value subdoc = make_document(kvp("key", "value"));
bsoncxx::document::value owner = make_document(kvp("v", subdoc.view()));
bsoncxx::document::view v = owner.view()["v"].get_document().value;
EXPECT(v == subdoc.view());
}

With Multiple Sub-Document Appends

void example() {
std::string keys[] = {"a", "b", "c"};
std::int32_t values[] = {1, 2, 3};
for (int i = 0; i < 3; ++i) {
doc.append(kvp(keys[i], values[i]));
}
}));
bsoncxx::document::view v = owner.view()["v"].get_document().value;
EXPECT(v == bsoncxx::from_json(R"({"a": 1, "b": 2, "c": 3})"));
}

With a Sub-Array

void example() {
bsoncxx::array::value subarr = make_array(1, 2.0, "three");
bsoncxx::document::value owner = make_document(kvp("v", subarr.view()));
bsoncxx::array::view v = owner.view()["v"].get_array().value;
EXPECT(v == subarr.view());
}

With Multiple Sub-Array Appends

void example() {
std::int32_t values[] = {1, 2, 3};
for (int i = 0; i < 3; ++i) {
arr.append(values[i]);
}
}));
bsoncxx::array::view v = owner.view()["v"].get_array().value;
EXPECT(v == bsoncxx::builder::basic::make_array(1, 2, 3));
}

From Raw Bytes

As a View

// {"key": "value"}
void example(const std::uint8_t* data, std::size_t length) {
bsoncxx::document::view doc{data, length};
EXPECT(doc == bsoncxx::from_json(R"({"key": "value"})"));
}

As a Value

// {"key": "value"}
void example(const std::uint8_t* data, std::size_t length) {
using deleter_type = bsoncxx::document::value::deleter_type;
std::uint8_t* raw = new std::uint8_t[length];
std::copy_n(data, length, raw);
deleter_type deleter = [](std::uint8_t* data) { delete[] data; };
bsoncxx::document::value doc{raw, length, deleter};
EXPECT(doc.view() == bsoncxx::from_json(R"({"key": "value"})"));
}

Create an Array

From a JSON String

Basic Example

void example() {
[1, 2.0, "three"]
)");
bsoncxx::document::view doc = owner.view();
EXPECT(doc["0"].get_int32().value == 1);
EXPECT(doc["1"].get_double().value == 2.0);
EXPECT(doc["2"].get_string().value == "three");
}

With Extended JSON

void example() {
[
{"$numberInt": "1"},
{"$numberLong": "2"},
{"$numberDouble": "3"}
]
)");
bsoncxx::document::view doc = owner.view();
EXPECT(doc["0"].get_int32().value == 1);
EXPECT(doc["1"].get_int64().value == 2);
EXPECT(doc["2"].get_double().value == 3.0);
}

With a Sub-Document

void example() {
[
{"key": "value"}
]
)");
bsoncxx::document::view v = doc.view()["0"].get_document().value;
EXPECT(v == bsoncxx::from_json(R"({"key": "value"})"));
}

With a Sub-Array

void example() {
[
[1, 2.0, "three"]
]
)");
bsoncxx::array::view sub = doc.view()["0"].get_array().value;
EXPECT(sub == bsoncxx::builder::basic::make_array(1, 2.0, "three"));
}

With a User-Defined Literal

void example() {
using namespace bsoncxx;
bsoncxx::document::value a = R"([1, 2])"_bson;
EXPECT(a == b);
}

Using the Basic Builder

Basic Example

void example() {
builder.append(std::int32_t{1}, 2.0, "three");
bsoncxx::array::value arr = builder.extract();
EXPECT(arr.view() == bsoncxx::builder::basic::make_array(1, 2.0, "three"));
}

With make_document

void example() {
bsoncxx::builder::basic::make_array(std::int32_t{1}, 2.0, "three");
bsoncxx::array::view arr = owner.view();
EXPECT(arr[0].get_int32().value == 1);
EXPECT(arr[1].get_double().value == 2.0);
EXPECT(arr[2].get_string().value == "three");
}

With concatenate

// a: [1]
// b: [2]
builder.append(bsoncxx::builder::concatenate(a));
builder.append(bsoncxx::builder::concatenate(b));
EXPECT(builder.view() == bsoncxx::builder::basic::make_array(1, 2));
}

With Multiple Appends

void example() {
builder.append(std::int32_t{1});
builder.append(2.0);
builder.append("three");
bsoncxx::array::value arr = builder.extract();
EXPECT(arr.view() == bsoncxx::builder::basic::make_array(1, 2.0, "three"));
}

To Create Multiple Documents

void example() {
builder.append(std::int32_t{1});
bsoncxx::array::value a_owner = builder.extract();
builder.clear();
builder.append(std::int64_t{2});
bsoncxx::array::value b_owner = builder.extract();
bsoncxx::array::view a = a_owner.view();
bsoncxx::array::view b = b_owner.view();
EXPECT(a[0].type() == bsoncxx::type::k_int32);
EXPECT(b[0].type() == bsoncxx::type::k_int64);
EXPECT(a[0].get_int32().value == 1);
EXPECT(b[0].get_int64().value == 2);
}

With a Value Type

void example() {
bsoncxx::builder::basic::make_array(std::int32_t{1}, 2.0, "three");
bsoncxx::array::view arr = owner.view();
EXPECT(arr[0].type() == bsoncxx::type::k_int32);
EXPECT(arr[1].type() == bsoncxx::type::k_double);
EXPECT(arr[2].type() == bsoncxx::type::k_string);
EXPECT(arr[0].get_int32().value == 1);
EXPECT(arr[1].get_double().value == 2.0);
EXPECT(arr[2].get_string().value == "three");
}

With a BSON Type

With a BSON Value

void example() {
std::int32_t{1},
2.0,
"three",
};
bsoncxx::builder::basic::make_array(values[0], values[1], values[2]);
EXPECT(arr.view() == bsoncxx::builder::basic::make_array(1, 2.0, "three"));
}

With a Sub-Document

void example() {
bsoncxx::document::value subdoc = make_document(kvp("key", "value"));
bsoncxx::array::value owner = make_array(subdoc.view());
bsoncxx::document::view v = owner.view()[0].get_document().value;
EXPECT(v == subdoc.view());
}

With Multiple Sub-Document Appends

void example() {
std::string keys[] = {"a", "b", "c"};
std::int32_t values[] = {1, 2, 3};
for (int i = 0; i < 3; ++i) {
doc.append(kvp(keys[i], values[i]));
}
});
bsoncxx::document::view v = owner.view()[0].get_document().value;
EXPECT(v == bsoncxx::from_json(R"({"a": 1, "b": 2, "c": 3})"));
}

With a Sub-Array

void example() {
bsoncxx::array::value arr = make_array(1, 2.0, "three");
bsoncxx::array::value owner = make_array(arr.view());
bsoncxx::array::view v = owner.view()[0].get_array().value;
EXPECT(v == arr.view());
}

With Multiple Sub-Array Appends

void example() {
std::int32_t values[] = {1, 2, 3};
for (int i = 0; i < 3; ++i) {
arr.append(values[i]);
}
});
bsoncxx::array::view v = owner.view()[0].get_array().value;
EXPECT(v == make_array(1, 2, 3));
}

From Raw Bytes

As a View

// [1, 2]
void example(const std::uint8_t* data, std::size_t length) {
bsoncxx::array::view arr{data, length};
}

As a Value

// [1, 2]
void example(const std::uint8_t* data, std::size_t length) {
using deleter_type = bsoncxx::array::value::deleter_type;
std::uint8_t* raw = new std::uint8_t[length];
std::copy_n(data, length, raw);
deleter_type deleter = [](std::uint8_t* data) { delete[] data; };
bsoncxx::array::value arr{raw, length, deleter};
EXPECT(arr.view() == bsoncxx::builder::basic::make_array(1, 2));
}

Access a Document Element

By Iteration

Basic Example

// {"a": 1, "b": 2.0, "c": "three"}
void example(bsoncxx::document::view doc) {
switch (e.type()) {
case bsoncxx::type::k_int32:
EXPECT(e.key() == "a");
EXPECT(e.get_int32().value == 1);
break;
case bsoncxx::type::k_double:
EXPECT(e.key() == "b");
EXPECT(e.get_double().value == 2.0);
break;
case bsoncxx::type::k_string:
EXPECT(e.key() == "c");
EXPECT(e.get_string().value == "three");
break;
}
}
}

Using Iterators

// {"a": 1, "b": 2}
void example(bsoncxx::document::view doc) {
EXPECT(doc.begin() != doc.end());
auto iter = doc.begin();
EXPECT(iter == doc.begin());
{
EXPECT(e.key() == "a");
EXPECT(e.get_int32().value == 1);
}
++iter;
EXPECT(iter->key() == "b");
EXPECT(iter->get_int32().value == 2);
{
auto iter_copy = iter++;
EXPECT(iter_copy != iter);
EXPECT(iter_copy->key() == "b");
EXPECT(iter_copy->get_int32() == 2);
}
EXPECT(iter == doc.end());
}

Using Algorithms

// {"a": 1, "b": 2.0, "c": "three"}
void example(bsoncxx::document::view doc) {
EXPECT(std::distance(doc.begin(), doc.end()) == 3);
std::vector<bsoncxx::document::element> elements;
std::copy_if(doc.begin(),
doc.end(),
std::back_inserter(elements),
return e.key() == "a" || e.type() == bsoncxx::type::k_string;
});
EXPECT(elements.size() == 2u);
EXPECT(elements[0].key() == "a");
EXPECT(elements[1].key() == "c");
}

By Key

Using find()

// {"a": 1, "b": 2}
void example(bsoncxx::document::view doc) {
EXPECT(doc.find("a") == doc.begin());
{
auto iter = doc.find("b");
EXPECT(iter != doc.end());
EXPECT(iter->key() == "b");
EXPECT(iter->get_int32().value == 2);
}
EXPECT(doc.find("x") == doc.end());
}

Using the Subscript Operator

// {"a": 1, "b": 2}
void example(bsoncxx::document::view doc) {
EXPECT(doc["a"]);
{
EXPECT(e.key() == "b");
EXPECT(e.get_int32().value == 2);
}
EXPECT(!doc["c"]); // Invalid element.
}

Access an Array Element

By Iteration

Basic Example

// [1, 2.0, "three"]
void example(bsoncxx::array::view arr) {
for (bsoncxx::array::element e : arr) {
switch (e.type()) {
case bsoncxx::type::k_int32:
EXPECT(e.key() == "0");
EXPECT(e.get_int32().value == 1);
break;
case bsoncxx::type::k_double:
EXPECT(e.key() == "1");
EXPECT(e.get_double().value == 2.0);
break;
case bsoncxx::type::k_string:
EXPECT(e.key() == "2");
EXPECT(e.get_string().value == "three");
break;
}
}
}

Using Iterators

// [1, 2]
void example(bsoncxx::array::view arr) {
EXPECT(arr.begin() != arr.end());
auto iter = arr.begin();
EXPECT(iter == arr.begin());
{
EXPECT(e.key() == "0");
EXPECT(e.get_int32().value == 1);
}
++iter;
EXPECT(iter->key() == "1");
EXPECT(iter->get_int32().value == 2);
{
auto iter_copy = iter++;
EXPECT(iter_copy != iter);
EXPECT(iter_copy->key() == "1");
EXPECT(iter_copy->get_int32() == 2);
}
EXPECT(iter == arr.end());
}

Using Algorithms

// [1, 2.0, "three"]
void example(bsoncxx::array::view arr) {
EXPECT(std::distance(arr.begin(), arr.end()) == 3);
std::vector<bsoncxx::array::element> elements;
std::copy_if(
arr.begin(), arr.end(), std::back_inserter(elements), [](const bsoncxx::array::element& e) {
return e.key() == "0" || e.type() == bsoncxx::type::k_string;
});
EXPECT(elements.size() == 2u);
EXPECT(elements[0].key() == "0");
EXPECT(elements[1].key() == "2");
}

By Key

Using find()

// [1, 2]
void example(bsoncxx::array::view arr) {
EXPECT(arr.find(0) == arr.begin());
{
auto iter = arr.find(1);
EXPECT(iter != arr.end());
EXPECT(iter->key() == "1");
EXPECT(iter->get_int32().value == 2);
}
EXPECT(arr.find(2) == arr.end());
}

Using the Subscript Operator

// [1, 2]
void example(bsoncxx::array::view arr) {
EXPECT(arr[0]);
{
EXPECT(e.key() == "1");
EXPECT(e.get_int32().value == 2);
}
EXPECT(!arr[2]); // Invalid element.
}

Query an Element

In a Document

For a Single Type

// {"a": 1, "b": 2.0, "c": "three"}
void example(bsoncxx::document::element e) {
if (e.type() == bsoncxx::type::k_int32) {
EXPECT(e.key() == "a");
bsoncxx::types::b_int32 v = e.get_int32();
EXPECT(v.type_id == bsoncxx::type::k_int32);
EXPECT(v.value == 1);
} else {
EXPECT(e.key() != "a");
}
}

For Multiple Types

// {"a": 1, "b": 2.0, "c": "three"}
void example(bsoncxx::document::element e) {
switch (e.type()) {
case bsoncxx::type::k_int32: {
EXPECT(e.key() == "a");
bsoncxx::types::b_int32 v = e.get_int32();
EXPECT(v.type_id == bsoncxx::type::k_int32);
EXPECT(v.value == 1);
break;
}
case bsoncxx::type::k_double: {
EXPECT(e.key() == "b");
bsoncxx::types::b_double v = e.get_double();
EXPECT(v.type_id == bsoncxx::type::k_double);
EXPECT(v.value == 2.0);
break;
}
case bsoncxx::type::k_string: {
EXPECT(e.key() == "c");
bsoncxx::types::b_string v = e.get_string();
EXPECT(v.type_id == bsoncxx::type::k_string);
EXPECT(v.value == "three");
break;
}
}
}

In an Array

For Single Type

// [1, 2.0, "three"]
void example(bsoncxx::array::element e) {
if (e.type() == bsoncxx::type::k_int32) {
EXPECT(e.key() == "0");
bsoncxx::types::b_int32 v = e.get_int32();
EXPECT(v.type_id == bsoncxx::type::k_int32);
EXPECT(v.value == 1);
} else {
EXPECT(e.key() != "0");
}
}

For Multiple Types

// [1, 2.0, "three"]
void example(bsoncxx::array::element e) {
switch (e.type()) {
case bsoncxx::type::k_int32: {
EXPECT(e.key() == "0");
bsoncxx::types::b_int32 v = e.get_int32();
EXPECT(v.type_id == bsoncxx::type::k_int32);
EXPECT(v.value == 1);
break;
}
case bsoncxx::type::k_double: {
EXPECT(e.key() == "1");
bsoncxx::types::b_double v = e.get_double();
EXPECT(v.type_id == bsoncxx::type::k_double);
EXPECT(v.value == 2.0);
break;
}
case bsoncxx::type::k_string: {
EXPECT(e.key() == "2");
bsoncxx::types::b_string v = e.get_string();
EXPECT(v.type_id == bsoncxx::type::k_string);
EXPECT(v.value == "three");
break;
}
}
}

Comparison

By Type

// {"a": {"$numberInt": "1"}, "b": {"$numberLong": "2"}}
void example(bsoncxx::document::element e) {
std::int32_t a{1};
std::int64_t b{2};
if (e.type() == bsoncxx::type::k_int32) {
EXPECT(e.key() == "a");
EXPECT(e.get_int32().value == a);
} else if (e.type() == bsoncxx::type::k_int64) {
EXPECT(e.key() == "b");
EXPECT(e.get_int64().value == b);
}
}

By BSON Value

// {"a": {"$numberInt": "1"}, "b": {"$numberLong": "2"}}
void example(bsoncxx::document::element e) {
if (e.get_value() == a) {
EXPECT(e.key() == "a");
} else if (e.get_value() == b) {
EXPECT(e.key() == "b");
}
if (e == va) {
EXPECT(e.key() == "a");
} else if (e == vb) {
EXPECT(e.key() == "b");
}
}

Obtain a BSON Value

From a BSON Type

As a View

void example() {
view_type v;
EXPECT(v.type() == bsoncxx::type::k_null);
EXPECT(v.get_null() == bsoncxx::types::b_null{});
v = view_type(v0);
EXPECT(v.type() == v0.type_id);
EXPECT(v.get_int32() == v0);
v = view_type(v1);
EXPECT(v.type() == v1.type_id);
EXPECT(v.get_double() == v1);
v = view_type(v2);
EXPECT(v.type() == v2.type_id);
EXPECT(v.get_string() == v2);
}

As a Value

void example() {
EXPECT(v.view().type() == bsoncxx::type::k_null);
EXPECT(v.view().get_null() == bsoncxx::types::b_null{});
EXPECT(v.view().type() == bsoncxx::type::k_int32);
EXPECT(v.view().get_int32().value == 1);
EXPECT(v.view().type() == bsoncxx::type::k_double);
EXPECT(v.view().get_double().value == 2.0);
EXPECT(v.view().type() == bsoncxx::type::k_string);
EXPECT(v.view().get_string().value == "three");
}

From a Document Element

As a View

// {"a": 1, "b": 2.0, "c": "three"}
void example(bsoncxx::document::element e) {
EXPECT(v.type() == e.type());
switch (v.type()) {
case bsoncxx::type::k_int32:
EXPECT(e.key() == "a");
EXPECT(v.get_int32() == e.get_int32());
break;
case bsoncxx::type::k_double:
EXPECT(e.key() == "b");
EXPECT(v.get_double() == e.get_double());
break;
case bsoncxx::type::k_string:
EXPECT(e.key() == "c");
EXPECT(v.get_string() == e.get_string());
break;
}
}

As a Value

void example() {
EXPECT(v.view().type() == bsoncxx::type::k_null);
EXPECT(v.view().get_null() == bsoncxx::types::b_null{});
v = bsoncxx::from_json(R"({"v": {"key": "value"}})") // Temporary object.
["v"]
.get_owning_value(); // Copy: no dangling.
EXPECT(v.view().type() == bsoncxx::type::k_document);
v = v.view().get_document().value["key"].get_string(); // Copy: no dangling.
EXPECT(v.view().type() == bsoncxx::type::k_string);
EXPECT(v.view().get_string().value == "value");
}

From an Array Element

As a View

// [1, 2.0, "three"]
void example(bsoncxx::array::element e) {
EXPECT(v.type() == e.type());
switch (v.type()) {
case bsoncxx::type::k_int32:
EXPECT(e.key() == "0");
EXPECT(v.get_int32() == e.get_int32());
break;
case bsoncxx::type::k_double:
EXPECT(e.key() == "1");
EXPECT(v.get_double() == e.get_double());
break;
case bsoncxx::type::k_string:
EXPECT(e.key() == "2");
EXPECT(v.get_string() == e.get_string());
break;
}
}

As a Value

void example() {
EXPECT(v.view().type() == bsoncxx::type::k_null);
EXPECT(v.view().get_null() == bsoncxx::types::b_null{});
v = bsoncxx::from_json(R"({"v": ["value"]})") // Temporary object.
["v"]
.get_owning_value(); // Copy: no dangling.
EXPECT(v.view().type() == bsoncxx::type::k_array);
v = v.view().get_array().value[0].get_string(); // Copy: no dangling.
EXPECT(v.view().type() == bsoncxx::type::k_string);
EXPECT(v.view().get_string().value == "value");
}

From a Value Type

void example() {
EXPECT(v.view().type() == bsoncxx::type::k_null);
EXPECT(v.view().get_null() == bsoncxx::types::b_null{});
v = std::int32_t{1};
EXPECT(v.view().type() == bsoncxx::type::k_int32);
EXPECT(v.view().get_int32().value == 1);
v = 2.0;
EXPECT(v.view().type() == bsoncxx::type::k_double);
EXPECT(v.view().get_double().value == 2.0);
v = std::string("three");
EXPECT(v.view().type() == bsoncxx::type::k_string);
EXPECT(v.view().get_string().value == "three");
}

With make_value

void example() {
{
view_type v = owner.view();
EXPECT(v.type() == bsoncxx::type::k_int32);
EXPECT(v.get_int32().value == 1);
}
{
view_type v = owner.view();
EXPECT(v.type() == bsoncxx::type::k_int64);
EXPECT(v.get_int64().value == 2);
}
{
value_type owner = bsoncxx::types::bson_value::make_value(std::string("three"));
view_type v = owner.view();
EXPECT(v.type() == bsoncxx::type::k_string);
EXPECT(v.get_string().value == "three");
}
}

Convert to a JSON String

From a Document

void example() {
std::uint8_t data[]{"three"}; // Base64: dGhyZWU=
auto data_len = static_cast<std::uint32_t>(sizeof(data) - 1u); // Exclude null terminator.
bsoncxx::types::b_binary binary{bsoncxx::binary_sub_type::k_binary, data_len, data};
kvp("a", std::int32_t{1}), // "$numberInt": "1"
kvp("b", std::int64_t{2}), // "$numberLong": "2"
kvp("c", binary) // "$binary": { "$base64": "dGhyZWU=", "subType": 00 }
);
bsoncxx::document::view doc = owner.view();
{
// Canonical Extended JSON:
// {
// "a": { "$numberInt": "1" },
// "b": { "$numberLong": "2" },
// "c": {
// "$binary": {
// "base64": "dGhyZWU=",
// "subType": "00"
// }
// }
// }
std::string json = bsoncxx::to_json(doc, ExtendedJsonMode::k_canonical);
EXPECT(
json ==
R"({ "a" : { "$numberInt" : "1" }, "b" : { "$numberLong" : "2" }, "c" : { "$binary" : { "base64" : "dGhyZWU=", "subType" : "00" } } })");
}
{
// Relaxed Extended JSON
// {
// "a": 1,
// "b": 2,
// "c": {
// "$binary": {
// "base64": "dGhyZWU=",
// "subType": "00"
// }
// }
// }
std::string json = bsoncxx::to_json(doc, ExtendedJsonMode::k_relaxed);
EXPECT(
json ==
R"({ "a" : 1, "b" : 2, "c" : { "$binary" : { "base64" : "dGhyZWU=", "subType" : "00" } } })");
}
{
// Legacy Extended JSON
// {
// "a": 1,
// "b": 2,
// "c": {
// "$binary": "dGhyZWU=",
// "$type": "00"
// }
// }
std::string json = bsoncxx::to_json(doc);
EXPECT(json == R"({ "a" : 1, "b" : 2, "c" : { "$binary" : "dGhyZWU=", "$type" : "00" } })");
}
{
std::string a = bsoncxx::to_json(doc);
std::string b = bsoncxx::to_json(doc, ExtendedJsonMode::k_legacy);
EXPECT(a == b);
}
}

From an Array

void example() {
std::uint8_t data[]{"three"}; // Base64: dGhyZWU=
std::uint32_t data_len{5u}; // Exclude null terminator.
bsoncxx::types::b_binary binary{bsoncxx::binary_sub_type::k_binary, data_len, data};
std::int32_t{1}, // "$numberInt": "1"
std::int64_t{2}, // "$numberLong": "2"
binary // "$binary": { "$base64": "dGhyZWU=", "subType": 00 }
);
bsoncxx::array::view arr = owner.view();
{
// Canonical Extended JSON:
// [
// { "$numberInt": "1" },
// { "$numberLong": "2" },
// {
// "$binary": {
// "base64": "dGhyZWU=",
// "subType": "00"
// }
// }
// ]
std::string json = bsoncxx::to_json(arr, ExtendedJsonMode::k_canonical);
EXPECT(
json ==
R"([ { "$numberInt" : "1" }, { "$numberLong" : "2" }, { "$binary" : { "base64" : "dGhyZWU=", "subType" : "00" } } ])");
}
{
// Relaxed Extended JSON
// [
// 1,
// 2,
// {
// "$binary": {
// "base64": "dGhyZWU=",
// "subType": "00"
// }
// }
// ]
std::string json = bsoncxx::to_json(arr, ExtendedJsonMode::k_relaxed);
EXPECT(json == R"([ 1, 2, { "$binary" : { "base64" : "dGhyZWU=", "subType" : "00" } } ])");
}
{
// Legacy Extended JSON
// [
// 1,
// 2,
// {
// "$binary": "dGhyZWU=",
// "$type": "00"
// }
// ]
std::string json = bsoncxx::to_json(arr);
EXPECT(json == R"([ 1, 2, { "$binary" : "dGhyZWU=", "$type" : "00" } ])");
}
{
std::string a = bsoncxx::to_json(arr);
std::string b = bsoncxx::to_json(arr, ExtendedJsonMode::k_legacy);
EXPECT(a == b);
}
}