Docs Menu
Docs Home
/ / /
C++ ドライバー

BSON との連携

項目一覧

  • ドキュメント ビルダ
  • リストビルダ
  • 「ワンオフ」ビルダ関数
  • 基本ビルダ
  • ループ内での配列の構築
  • BSON ドキュメントの所有
  • 所有権のない BSON ドキュメント(ビュー)
  • 任意に所有できる BSON ドキュメント(view_or_value)
  • BSON ドキュメントの有効期間
  • BSON ドキュメントの印刷
  • BSON ドキュメントからのフィールドの取得
  • BSON types

mongocx ドライバーには新しいライブラリ bsoncx が付属します。 この記事では、このライブラリにあるさまざまな型の一部と、それぞれを使用する方法とタイミングについて説明しGo 。 詳細とサンプル コードについては、 の例を参照してください。

  1. ドキュメント ビルダ

  2. BSON ドキュメントの所有(値)

  3. 所有権のない BSON ドキュメント(ビュー)

  4. 任意に所有する BSON ドキュメント(view_or_value)

  5. BSON ドキュメントの有効期間

  6. BSON ドキュメントの印刷

  7. BSON ドキュメントからのフィールドの取得

  8. BSON types

bsoncx ライブラリは、BSON を構築するための 4 つのインターフェースを提供します。いずれも、ワンオフ関数、基本ビルダ、リスト ビルダ、ストリームベースのビルダです。

bsoncx::Builder::basic::document bsoncx::Builder::stream::document

BSON ドキュメントと配列を作成するさまざまな方法はすべて同等です。 すべてのインターフェースは同じ結果を提供します。使用するインターフェースの選択は完全に存在します。

BSON ドキュメントまたは配列を作成する最も簡単な方法は、JSON のようなリスト ビルダを使用することです。

// { "hello": "world" }
bsoncxx::builder::list list_builder = {"hello", "world"};
bsoncxx::document::view document = list_builder.view().get_document();

この例では、リスト ビルダのより高度な使用方法を示しています。

「One-OFF」ビルダは、1 回の呼び出しでドキュメントと配列を作成します。 これらは、オブジェクトを作成するために追加のロジック(条件やループなど)を使用する必要がない場合に使用できます。

using bsoncxx::builder::basic::kvp;
// { "hello": "world" }
bsoncxx::document::value document = bsoncxx::builder::basic::make_document(kvp("hello", "world"));
using bsoncxx::builder::basic::kvp;
// { "hello" : "world" }
bsoncxx::builder::basic::document basic_builder{};
basic_builder.append(kvp("hello", "world"));
bsoncxx::document::value document = basic_builder.extract();

この例では、基本ビルダのより高度な使用方法を示しています。

// { "hello" : "world" }
using bsoncxx::builder::stream;
bsoncxx::document::value document = stream::document{} << "hello" << "world" << stream::finalize;

この例では、ストリーム ビルダのより高度な用途が示されています。

注意

新しい各値を適切に追加するには、ストリーム ビルダがネスト レベルやビルダに追加された最新の値のタイプなど、現在のドキュメントの状態を追跡する必要があります。 この状態が変化した後、初期ストリーム ビルダを再利用してはなりませ。つまり、複数のステートメントにわたってストリーム ビルダを使用してドキュメントを構築する場合は、中間値を新しい変数に保存する必要があります。 これを適切に行うことは困難であり、コンパイラー エラー メッセージが混乱する可能性があるため、ストリーム ビルダの使用は推奨されません。 代わりに、 基本 ビルダまたはワンオフ ビルダ関数を使用することをお勧めします。

場合によっては、 ループを使用して配列を構築する必要があります。 基本ビルダを使用すると、ループ内で appendを呼び出すだけで最上位の配列を構築できます。

// [ 1, 2, 3 ]
const auto elements = {1, 2, 3};
auto array_builder = bsoncxx::builder::basic::array{};
for (const auto& element : elements) {
array_builder.append(element);
}

ループでサブ配列を構築するには、 Lambdaを append に渡します(またはサブ配列に配列ではなくドキュメントが含まれている場合は kvp の 2 番目の引数として):

// { "foo" : [ 1, 2, 3 ] }
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::sub_array;
const auto elements = {1, 2, 3};
auto doc = bsoncxx::builder::basic::document{};
doc.append(kvp("foo", [&elements](sub_array child) {
for (const auto& element : elements) {
child.append(element);
}
}));

ストリーム ビルダで配列を作成するときは、ストリーム ビルダで<<演算子を使用する際の戻り値の型が単一ではないことに注意することが重要です。 ループ内で配列を適切に構築するには、型が変更されたときにストリーム ビルダによって返される中間値を変数に保存する必要があります。 ループを使用してストリーム ビルダから配列を構築しようとすると、次のようになります。

// { "subdocs" : [ { "key" : 1 }, { "key" : 2 }, { "key" : 3 } ], "another_key" : 42 }
using namespace bsoncxx;
builder::stream::document builder{};
auto in_array = builder << "subdocs" << builder::stream::open_array;
for (auto&& e : {1, 2, 3}) {
in_array = in_array << builder::stream::open_document << "key" << e
<< builder::stream::close_document;
}
auto after_array = in_array << builder::stream::close_array;
after_array << "another_key" << 42;
document::value doc = after_array << builder::stream::finalize;
std::cout << to_json(doc) << std::endl;

注意

すべてのストリーム操作の結果はキャプチャされる必要があるため、上記の for ループ内の 1 つのステートメントを複数のステートメントに分割する場合は、それぞれの中間結果をキャプチャする必要があります。 さらに、ループ本体内の最後のステートメントは、その結果を in_array オブジェクトに再度割り当てて、ループが一貫した状態で再起動するようにする必要があります。

for (auto && e : {1, 2, 3}) {
auto open_state = in_array << builder::stream::open_document;
auto temp_state = open_state << "key" << e;
in_array = temp_state << builder::stream::close_document;
}

bsoncx::document::value

このタイプは、データのバッファを所有する実際の BSON ドキュメントを表します。 これらのドキュメントは、 extract()を呼び出してビルダから構築できます。

bsoncxx::document::value basic_doc{basic_builder.extract()};
bsoncxx::document::value stream_doc{stream_builder.extract()};

extract()を呼び出した後、ビルダは移動済み状態になるため、使用しないでください。

ストリーム ビルダ インターフェースとfinalizeトークンを使用して、1 行でbsoncxx::document::valueを作成できます。 finalizeは一時ストリーム ビルダからdocument::valueを返します。

// { "finalize" : "is nifty" }
bsoncxx::document::value one_line = bsoncxx::builder::stream::document{} << "finalize" << "is nifty" << bsoncxx::builder::stream::finalize;

bsoncx::document::view

このタイプは、所有するbsoncxx::document::valueのビューです。

bsoncxx::document::view document_view{document_value.view()};

document::valueは暗黙的にdocument::viewに変換されます。

bsoncxx::document::view document_view{document_value};

パフォーマンスが重要なコードでは、過剰なコピーを回避できるため、値を使用するよりもビューを渡すことをお勧めします。 また、ドキュメントのビューを渡すと、ドキュメントを複数回使用できます。

// { "copies" : { "$gt" : 100 } }
auto query_value = document{} << "copies" << open_document << "$gt" << 100 << close_document << finalize;
// Run the same query across different collections
auto collection1 = db["science_fiction"];
auto cursor1 = collection1.find(query_value.view());
auto collection2 = db["cookbooks"];
auto cursor2 = collection2.find(query_value.view());

多くのドライバー メソッドはdocument::view_or_value パラメーターを受け取ります。たとえば、 run_command は次のようになります。

bsoncxx::document::value run_command(bsoncxx::document::view_or_value command);

このようなメソッドでは、 document::viewまたはdocument::valueのいずれかが含まれます。 document::valueが渡される場合、r 値参照によって渡される必要があるため、ドキュメントの所有権は メソッドに転送されます。

document::value ping = document{} << "ping" << 1 << finalize;
// You can pass a document::view into run_command()
db.run_command(ping.view());
// Or you can move in a document::value
db.run_command(std::move(ping));

ドライバーを使用するために、 view_or_value型を直接作成する必要はありません。 これらはドライバー メソッドが所有方法または非所有方法のいずれかでドキュメントを受け取れるようにするための便宜的メソッドとして提供されています。 view_or_valueタイプは、次のセクションで説明するライフタイムの問題の一部を軽減するのにも役立ちます。

document::valueタイプは、それを使用するdocument::viewタイプよりも優先されます。 基になる値がクリーンアップされると、ビューにはバランシングされたポインターが残ります。 新しく作成されたドキュメントのビューを返すメソッドを検討します。

bsoncxx::document::view make_a_dangling_view() {
bsoncxx::builder::basic::document builder{};
builder.append(kvp("hello", "world"));
// This creates a document::value on the stack that will disappear when we return.
bsoncxx::document::value stack_value{builder.extract()};
// We're returning a view of the local value
return stack_value.view(); // Bad!!
}

このメソッドは、使用しないでください。

// This view contains a dangling pointer
bsoncxx::document::view dangling_view = make_a_dangling_view(); // Warning!!

ビルダからビューを作成しようとすると、 extract()から返された一時値はキャプチャされないため、同様にリスクのあるビュー オブジェクトが作成されます。

bsoncxx::builder::stream::document temp_builder{};
temp_builder << "oh" << "no";
bsoncxx::document::view dangling_view = temp_builder.extract().view(); // Bad!!

bsoncx::to_json()

bsoncx ライブラリには、BSON ドキュメントを簡単に検査できるように string に変換する便利なメソッドが付属しています。

bsoncxx::document::value = document{} << "I am" << "a BSON document" << finalize;
std::cout << bsoncxx::to_json(doc.view()) << std::endl;

from_json() という類似メソッドもあります。 、既存の JSON string からドキュメント:: 値を構築します。

[ ] 演算子は、値を検索するために BSON ドキュメントに到達します。

// doc_view = { "store" : "Key Foods", "fruits" : [ "apple", "banana" ] }
auto store = doc_view["store"];
auto first_fruit = doc_view["fruits"][0];

これにより、実際の目的値を保持するbsoncxx::document::elementが返されます。

document::element store_ele{doc_view["store"]};
if (store_ele) {
// this block will only execute if "store" was found in the document
std::cout << "Examining inventory at " << to_json(store_ele.get_value()) << std::endl;
}

この機能は、次の でより詳細に示されています この例では、

BSON 仕様 サポートされているタイプのリストを提供します。これらは b_XX を使用して C++ では表されます 型ラッパー。

一部の BSON types は必ずしもラップするネイティブ表現を持つ必要はなく、特殊なクラス経由で実装されます。

bsoncxx::decimal128クラスは、 128ビット IEEE 754 - 2008の 10 進数浮動小数点値を表します。 ユーザーはこれらを string に変換したり、string から変換したりすることを想定していますが、ユーザーがネイティブ 10 進数128型に変換する必要がある場合は、64 ビットの低値と高値のビット値にアクセスできます。

bsoncxx::decimal128この例 では、 との連携方法がわかります。

戻る

接続プール