Docs Menu
Docs Home
/ / /
C++ 드라이버

BSON으로 작업하기

이 페이지의 내용

  • 문서 빌더
  • 목록 작성기
  • "일회성" 빌더 함수
  • 기본 빌더
  • 루프에서 배열 만들기
  • BSON 문서 소유
  • 비소유 BSON 문서(뷰)
  • 선택적으로 소유하는 BSON 문서(view_or_value)
  • BSON 문서 수명
  • BSON 문서 인쇄
  • BSON 문서에서 필드 가져오기
  • BSON 유형

mongocxx 운전자 는 새로운 라이브러리인 bsoncxx와 함께 제공됩니다. 이 문서에서는 이 라이브러리의 다양한 유형과 각각을 사용하는 방법과 시기에 대해 설명 Go . 자세한 내용과 예시 코드는 예제를 참조하세요.

  1. 문서 빌더

  2. BSON 문서 소유(값)

  3. 비소유 BSON 문서(뷰)

  4. 선택적으로 소유하는 BSON 문서(view_or_value)

  5. BSON 문서 수명

  6. BSON 문서 인쇄

  7. BSON 문서에서 필드 가져오기

  8. BSON 유형

bsoncxx 라이브러리는 BSON 빌드를 위한 네 가지 인터페이스, 즉 일회성 함수, 기본 빌더, 목록 빌더 및 스트림 기반 빌더를 제공합니다.

bsoncxx::builder::basic::document bsoncxx::builder::stream::document

BSON 문서와 배열을 만드는 다양한 방법은 모두 동일합니다. 모든 인터페이스는 동일한 결과를 제공하며, 어떤 인터페이스를 사용할지 선택하는 것은 전적으로 미적입니다.

BSON 문서 또는 배열을 만드는 가장 간단한 방법은 JSON과 유사한 목록 빌더를 사용하는 것입니다.

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

이 예시 에서는목록 작성기의 고급 사용 방법을 보여 줍니다.

'일회성' 빌더는 한 번의 호출로 문서와 배열을 생성합니다. 이는 객체를 생성하는 데 추가 로직(예: 조건부 또는 루프)을 사용할 필요가 없는 경우에 사용할 수 있습니다.

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 의 두 번째 인수로 전달).

// { "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 루프 내 단일 문을 여러 문으로 분할하려면 각 중간 결과를 캡처해야 합니다. 또한 루프 본문 내의 마지막 문은 결과를 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;
}

bsoncxx::document::value

이 유형은 데이터 버퍼를 소유한 실제 BSON 문서를 나타냅니다. 이러한 문서는 빌더에서 extract() 을(를) 호출하여 구성할 수 있습니다.

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

extract() 호출 후 빌더는 이동 시작 상태이므로 사용해서는 안 됩니다.

스트림 빌더 인터페이스와 finalize 토큰을 사용하여 한 줄에 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;

bsoncxx::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!!

bsoncxx::to_json()

bsoncxx 라이브러리에는 쉽게 검사할 수 있도록 BSON 문서를 문자열로 변환하는 편리한 메서드가 제공됩니다.

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

from_json() 과 유사한 메서드가 있습니다. 을(를) 사용하여 기존 JSON 문자열에서 문서 :values를 빌드 합니다.

[ ] 연산자는 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 사양 지원되는 유형 목록을 제공합니다. 이는 C++ 에서 b_xxx 를 사용하여 표시됩니다. 유형 래퍼.

일부 BSON types는 반드시 래핑할 네이티브 표현이 있을 필요는 없으며 특수 클래스를 통해 구현됩니다.

bsoncxx::decimal128 클래스는 128비트 IEEE 754-2008 10진수 부동 소수점 값을 나타냅니다. 사용자가 이를 문자열로 변환하거나 그 반대로 변환해야 하지만 사용자가 네이티브 십진수128 유형으로 변환해야 하는 경우 낮은 및 높은 64비트 값에 대한 액세스를 제공합니다.

이 예시 에서로 작업하는 방법을 확인할 수 있습니다.bsoncxx::decimal128

돌아가기

연결 풀