Mongodb系列(二)——C++驱动mongocxx的装置与应用
本文次要介绍如何装置和应用mongodb的C++驱动,mongocxx。官网链接mongocxx、api文档、应用示例。
装置
作者应用的是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;}