C++驱动mongocxx的安装与使用

本文主要介绍如何安装和使用mongodb的C++驱动,mongocxx。官网链接mongocxxapi文档使用示例

安装

作者使用的是ubuntu20.04操作系统,mongodb版本为4.4.11。

安装C驱动

首先下载安装包,链接为https://github.com/mongodb/mo...

// 进入目录
$ cd mongo-c-driver
$ mkdir -p build && cd build
$ cmake ..
$ sudo make && make install

安装C++驱动

下载安装包,链接为https://github.com/mongodb/mo...

$ cd mongo-cxx-driver
$ mkdir -p build && cd build
$ cmake … -DCMAKE_INSTALL_PREFIX=/usr/local
$ make && make install

使用

这里统一使用cmake来管理包。
链接方式如下,在项目第一层的CMakeLists.txt文件中加上

find_package(mongocxx REQUIRED)
find_package(bsoncxx REQUIRED)
include_directories(${LIBMONGOCXX_INCLUDE_DIR})
include_directories(${LIBBSONCXX_INCLUDE_DIR})
include_directories("/usr/local/include/mongocxx/v_noabi")
include_directories("/usr/local/include/bsoncxx/v_noabi")
include_directories("/usr/local/include/libmongoc-1.0")
include_directories("/usr/local/include/libbson-1.0")
include_directories("/usr/local/lib")
link_directories(
    /usr/local/lib/mongocxx/v_noabi
    /usr/local/lib/bsoncxx/v_noabi
)

对于我们要生成的可执行文件所在目录的CMakeLists.txt文件中添加

add_executable(YourTarget main.cpp)
target_link_libraries(YourTarget
    mongo::mongocxx_shared
)

以上步骤即引入mongocxx成功。

连接

连接是通过mongocxx::uri这个类来实现的。代码如下

#include <iostream>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/cursor.hpp>

int main(int argc, char *argv[])
{
    // 27017是默认端口
    mongocxx::uri uri{"mongodb://localhost:27017"};
    // 创建一个client客户端
    mongocxx::client client = mongocxx::client{uri};
    mongocxx::database db = client["db"];
    mongocxx::collection coll = db["coll"];
    // 选择了数据库db,表coll
}

基础增删改查

这里简单展示基础的增删改查。需要先构建bson文档对象,才能调用增删改查接口,构建方法有多种,这里简单介绍stream构建方式(其他参考官网)。

#include <cstdint>
#include <iostream>
#include <vector>
#include <bsoncxx/json.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/builder/stream/array.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>

using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;

int main()
{
    /* 初始化,创建一个客户端连接 */
    mongocxx::uri uri("mongodb://localhost:27017");
    mongocxx::client client(uri);

    /* 访问指定的数据库和集合 */
    mongocxx::database db = client["test_db"];
    mongocxx::collection coll = db["test_collection"];
    // db.drop();

    // 创建一个json文档
    // 创建一个json文档(Document)
    // {
    //    "name" : "MongoDB",
    //    "type" : "database",
    //    "count" : 5,
    //    "versions": [ "v1.0", "v2.0", "v3.0" ],
    //    "info" : {
    //                "x" : 1314,
    //                "y" : 520
    //             }
    // }
    auto builder = bsoncxx::builder::stream::document{};
    bsoncxx::document::value doc_value = builder
                                         << "name"
                                         << "MongoDB"
                                         << "type"
                                         << "database"
                                         << "count" << 5
                                         << "versions" << bsoncxx::builder::stream::open_array
                                         << "v1.0"
                                         << "v2.0"
                                         << "v3.0"
                                         << close_array
                                         << "info" << bsoncxx::builder::stream::open_document
                                         << "x" << 1314
                                         << "y" << 520
                                         << bsoncxx::builder::stream::close_document
                                         << bsoncxx::builder::stream::finalize;
    bsoncxx::document::view view = doc_value.view();
    bsoncxx::document::element element = view["name"];
    // 插入文档
    bsoncxx::stdx::optional<mongocxx::result::insert_one> insert_one_result = coll.insert_one(doc_value.view());
    bsoncxx::oid oid = insert_one_result->inserted_id().get_oid().value;
    std::string insert_id = oid.to_string();
    std::cout << "Insert one document, return id is " << insert_id << std::endl;

    // 查询单个文档
    bsoncxx::stdx::optional<bsoncxx::document::value> maybe_result = coll.find_one({});
    bsoncxx::document::view view2 = maybe_result->view();
    auto find_one_id = view2["_id"].get_oid().value.to_string();
    std::cout << "\nfind one document, return id is " << find_one_id << std::endl;

    // 查询所有文档
    std::cout << "\nfind all documents, return values:\n";
    mongocxx::cursor cursor = coll.find({});
    for (bsoncxx::document::view docView : cursor)
    {
        std::cout << bsoncxx::to_json(docView) << std::endl;
    }
    // 查询匹配过滤器的文档
    // {"count":5}
    bsoncxx::stdx::optional<bsoncxx::document::value> find_one_result =
        coll.find_one(document{} << "count" << 5 << finalize);
    if (find_one_result)
    {
        std::cout << "\nspecify query filter, find_one() return values:" << std::endl;
        std::cout << bsoncxx::to_json(find_one_result->view()) << std::endl;
    }

    // 复杂过滤器
    // 5 <= count < 10
    auto filter = document{} << "count" << open_document << "$gte" << 5 << "$lte" << 10 << close_document << finalize;
    auto order = document{}; // << "_id" << -1 << finalize;
    auto field = document{} << "_id" << 1 << "count" << 1 << finalize;
    mongocxx::options::find ops = mongocxx::options::find{};
    ops.sort(order.view()).projection(field.view()).limit(3);
    mongocxx::cursor cur = coll.find(filter.view(), ops);
    std::cout << "\nspecify query filter, find() return values:\n";
    for (bsoncxx::document::view docView : cur)
    {
        std::cout << bsoncxx::to_json(docView) << std::endl;
    }
    // 更新单个文档
    mongocxx::stdx::optional<mongocxx::result::update> update_one_result =
        coll.update_one(document{} << "count" << 1 << finalize,
                        document{} << "$set" << open_document << "name"
                                   << "MongoDB更新测试" << close_document << finalize);

    bsoncxx::stdx::optional<mongocxx::result::update> update_many_result =
        coll.update_many(
            document{} << "count" << open_document << "$lt" << 5 << close_document << finalize,
            document{} << "$inc" << open_document << "count" << 1 << close_document << finalize);
    if (update_many_result)
    {
        std::cout << "\nupdate " << update_many_result->modified_count() << " documents\n";
    }
    // 删除单个文档
    mongocxx::stdx::optional<mongocxx::result::delete_result> delete_one_result =
        coll.delete_one(document{} << "count" << 5 << finalize);
    if (delete_one_result)
    {
        std::cout << "\ndelete " << delete_one_result->deleted_count() << " document\n";
    }
    return 0;
}

连接池

在构建在线服务时,我们不可能在每次做crud时再创建连接,常见的方式是使用连接池,进程初期创建好连接资源,需要增删改查的时候从连接池获取资源再释放。mongocxx已经为我们提供了该支持。

#include <iostream>
#include <ostream>
#include <sstream>
#include <vector>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/pool.hpp>
#include <mongocxx/uri.hpp>

int main() {
    // 两个参数分别表示最小的连接数(初始时候分配)和最大连接数(最小资源数分配不够的时候重新申请到最大连接数)
    mongocxx::uri uri{"mongodb://localhost:27017/?minPoolSize=3&maxPoolSize=3"};
    mongocxx::pool pool{uri};
    // 分配一个连接资源,返回类型是对mongocxx::client的包装,这是一个RAII类型,不需要显式释放,析构后会自动回收资源。
    mongocxx::pool::entry entry = pool.acquire();
    mongocxx::database db = (*entry)["db_test"];
    mongocxx::database coll = db["coll_test"];
    return 0;
}

事务

MongoDB-4.0之后的版本是支持事务的。这里简单介绍如何利用MongoCXX执行MongoDB的事务。

#include <iostream>
#include <vector>

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/exception/exception.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/exception/exception.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/exception/operation_exception.hpp>
#include <mongocxx/pool.hpp>
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::open_document;

int main(int argc, char **argv)
{
    int N_INSERTS = 1;
    mongocxx::uri client_uri = mongocxx::uri("mongodb://localhost:30011,localhost:30012,localhost:30013/");
    mongocxx::client client = mongocxx::client(client_uri);
    mongocxx::database db = client["db"];
    mongocxx::collection coll = db["coll"];
    // 开启一个会话session
    mongocxx::client_session session = client.start_session();
    // 可以这么从会话中获取session:session.client(),函数传递session参数,函数内自己获取client;
    document builder{};
    auto before = builder << "name"
                          << "mongodb"
                          << "array" << open_array;
    before = before << open_document << "1" << 1 << close_document;
    before = before << open_document << "2" << 2 << close_document;
    auto doc = before << close_array << finalize;
    session.start_transaction();
    try
    {
        coll.insert_one(doc.view());
    }
    catch (std::exception &e)
    {
        std::cout << "exception:" << e.what() << std::endl;
        session.abort_transaction();    //终止事务
    }
    // 提交事务
    coll.commit_transaction();
    return 0;
}

转自:https://segmentfault.com/a/1190000041365274

posted @ 2023-02-07 14:45  MasonLee  阅读(1164)  评论(0编辑  收藏  举报