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;
}