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

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

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

1. bsoncxx

文件夹下包含的cpp

这里写图片描述

对应于API中的

这里写图片描述
从实用的角度讲,通过代码分析用法更为有效。
关于bsoncxx::builder中的basic,streamcore
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中的多不少
见下篇博客吧,写在一起太长了。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值