您的位置:首页 > 数据库 > Mongodb

MongoDB&C++开发 (三) C++ Driver 浅析(结合mongo-cxx-driver/examples中代码)

2017-09-27 22:13 561 查看

MongoDB C++ Driver API 官方文档链接

在mongo-cxx-driver/examples文件夹下,有bsoncxx和mongocxx两个代码文件夹,对应于这两个命名空间。

1. bsoncxx

文件夹下包含的cpp



对应于API中的



从实用的角度讲,通过代码分析用法更为有效。

关于
bsoncxx::builder
中的
basic
,
stream
core


builder_core.cpp中有这样一句注释

// bsoncxx::builder::core is a low-level primitive that can be useful for building other
// BSON abstractions. Most users should just use builder::stream or builder::basic.


而我自己觉得,
builder::basic
也是一种比较传统的创建
builder::basic::document{}
文档的方式,如果创建比较复杂的文档,还是太繁琐了,所以实用
builder::stream
流式的方式比较好。

现选择builder_stream.cpp和getting_values.cpp进行分析:

1.1 流式构造文档

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/array.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/types.hpp>

using namespace bsoncxx;

int main(int, char**) {
using builder::stream::document;
using builder::stream::array;

// bsoncxx::builder::stream presents an iostream like interface for succintly
// constructing complex BSON objects.

// stream::document builds a BSON document 构造一个BSON文档
auto doc = document{};
// stream::array builds a BSON array 构造一个BSON数组
auto arr = array{};

// We append keys and values to documents using the '<<' operator;使用<<运算符
// 连接key和value
doc << "myKey"
<< "myValue";
// We can chain any number of keys and values
doc << "foo" << types::b_bool{false} << "baz" << types::b_int32{1234} << "quz"
<< types::b_double{1.234};

// For arrays, everything just becomes a value, array里面的值都是value而不是key
arr << 1 << 2 << types::b_bool{true};

// The stream namespace includes some helpers that can be used similarly
// to the stream manipulators in <iomanip>
// To build a subdocument, use open_document and close_document
// 文档里面嵌套文档使用open_document和close_document
using builder::stream::open_document;
using builder::stream::close_document;
doc << "mySubDoc" << open_document << "subdoc key"
<< "subdoc value" << close_document;
// To build a subarray, use open_array and close_array
// 数组里面嵌套数组,使用open_array和close_array
using builder::stream::open_array;
using builder::stream::close_array;
doc << "mySubArr" << open_array << 1 << types::b_bool{false} << "hello" << close_array;

// There is a special finalize helper that converts a stream to its underlying bson value
// this is useful for writing one-liners, for example
using builder::stream::finalize;
auto myQuery = document{} << "foo"
<< "bar" << finalize;

// There is a special concatenate helper to add all keys and corresponding values from one
//将一个文档中的内容加到另一个文档中(保持其key-value的对应关系),可以使用concatenate
// document into another.
using bsoncxx::builder::concatenate;
doc << concatenate(myQuery.view());
// `doc` now looks like:
// {
//   "myKey": "myValue",
//   ...
//   "mySubArr": [...],
//   "foo": "bar"
// }

// To nest an existing bsoncxx::document::value into a builder stream, you can create a
// types::b_document and append it. Alternatively you can open a new document and concatenate
// the value in. Or, simplest, is just to stream in the view.
bsoncxx::document::value nestedValue = document{} << "nested" << true << finalize;
document topLevelDoc{};
topLevelDoc << "subDoc1" << types::b_document{nestedValue.view()} << "subDoc2" << open_document
<< concatenate(nestedValue.view()) << close_document << "subDoc3" << nestedValue
<< finalize;

// `topLevelDoc` now looks like:
// {
//     "subDoc1": {
//         "nested": true
//     },
//     "subDoc2": {
//         "nested": true
//     },
//     "subDoc3": {
//         "nested": true
//     }
// }
}


1.2 流式构造文档并通过[“key”] or [index]访问值

#include <bsoncxx/builder/stream/array.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/config/prelude.hpp>
#include <bsoncxx/types.hpp>

using namespace bsoncxx;

int main(int, char**) {
using namespace builder::stream;

builder::stream::document build_doc;
// {
//     "_id" : 1,
//     "name" : { "first" : "John", "last" : "Backus" },
//     "contribs" : [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ],
//     "awards" : [
//                {
//                  "award" : "W.W. McDowell Award",
//                  "year" : 1967,
//                  "by" : "IEEE Computer Society"
//                },
//                { "award" : "Draper Prize",
//                  "year" : 1993,
//                  "by" : "National Academy of Engineering"
//                }
//     ]
// }
//name是key,它对应的value值是一个文件,里面有两个键值对,分别是"first" : "John"和 "last" : "Backus"。
//contribs是key,它对应的value是一个数组,数组里面有四个value:"Fortran", "ALGOL", "Backus-Naur Form", "FP"
//awards是key,它对应的value是一个数组,数组里面有两个文档,第一个文档里面有三个键值对,第二个文档里面也有三个键值对
//至此,使用builder::stream::document可以实现构造一个比较复杂的文件了。
build_doc << "_id" << 1 << "name" << open_document << "first"
<< "John"
<< "last"
<< "Backus" << close_document << "contribs" << open_array << "Fortran"
<< "ALGOL"
<< "Backus-Naur Form"
<< "FP" << close_array << "awards" << open_array << open_document << "award"
<< "W.W. McDowell Award"
<< "year" << 1967 << "by"
<< "IEEE Computer Society" << close_document << open_document << "award"
<< "Draper Prize"
<< "year" << 1993 << "by"
<< "National Academy of Engineering" << close_document << close_array;

auto doc = build_doc.view();

// Once we have the document view, we can use ["key"] or [index] notation to reach into nested
// documents or arrays.
//用流式方式构造的文件,可以通过类似下标的方式实现随机访问,这里使用auto关键字可以简化很多工作,也不容易出错。

auto awards = doc["awards"];//名为awards的key所对应的value---是一个包含两个document的array
auto first_award_year = awards[0]["year"];//awards对应的array里面的第一个array元素,即
//{
//                  "award" : "W.W. McDowell Award",
//                  "year" : 1967,
//                  "by" : "IEEE Computer Society"
//                },
//这个文档中名为year的key对应的value
auto second_award_year = doc["awards"][1]["year"];
auto last_name = doc["name"]["last"];

// If the key doesn't exist, or index is out of bounds, we get invalid elements.
//如果key不存在或者a要访问的rray的index越界,会得到无效的元素
auto invalid1 = doc["name"]["middle"];
auto invalid2 = doc["contribs"][1000];
if (invalid1 || invalid2) {
BSONCXX_UNREACHABLE;  // Not reached.
}

// Similarly, indexed access (either by string or numeric index) into a type that is not
// a document or an array yields invalid eleemnts.

auto invalid3 = doc["_id"]["invalid"];
auto invalid4 = doc["name"][3];
if (invalid3 || invalid4) {
BSONCXX_UNREACHABLE;  // Not reached.
}

// Make all variables used.
return (awards && first_award_year && second_award_year && last_name) ? EXIT_SUCCESS
: EXIT_FAILURE;
}


2. mongocxx

mongocxx文件夹中的文件比bsoncxx中的多不少

见下篇博客吧,写在一起太长了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mongodb c++-API bson