mongocxx — MongoDB C++ 驱动
mongocxx 是 MongoDB 官方 C++ 驱动,提供现代 C++ API,支持 BSON 文档操作、聚合管道、事务、GridFS 等完整功能。
安装
bash
# Ubuntu(先安装 mongoc)
sudo apt install libmongoc-dev libbson-dev
# 然后编译 mongocxx:https://mongocxx.org/mongocxx-driver/current/installation/
# vcpkg
vcpkg install mongo-cxx-driver
# CMake
find_package(mongocxx REQUIRED)
find_package(bsoncxx REQUIRED)
target_link_libraries(myapp PRIVATE mongo::mongocxx_shared mongo::bsoncxx_shared)连接与基本操作
cpp
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/builder/stream/document.hpp>
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::finalize;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::close_array;
int main() {
// 必须先创建 instance(全局唯一)
mongocxx::instance inst{};
// 连接
mongocxx::client client{mongocxx::uri{"mongodb://localhost:27017"}};
// 获取数据库和集合
auto db = client["mydb"];
auto coll = db["users"];
// 插入单个文档
auto doc = document{}
<< "name" << "Alice"
<< "age" << 30
<< "email" << "alice@example.com"
<< "tags" << open_array << "cpp" << "programming" << close_array
<< finalize;
auto result = coll.insert_one(doc.view());
if (result) {
auto id = result->inserted_id().get_oid().value.to_string();
std::cout << "插入 ID: " << id << "\n";
}
// 批量插入
std::vector<bsoncxx::document::value> docs;
for (int i = 0; i < 100; ++i) {
docs.push_back(document{}
<< "name" << ("User" + std::to_string(i))
<< "age" << (20 + i % 50)
<< finalize);
}
coll.insert_many(docs);
}查询
cpp
// 查询所有
auto cursor = coll.find({});
for (const auto& doc : cursor) {
std::cout << bsoncxx::to_json(doc) << "\n";
}
// 条件查询
auto filter = document{} << "age" << bsoncxx::builder::stream::open_document
<< "$gt" << 25
<< bsoncxx::builder::stream::close_document
<< finalize;
auto cursor2 = coll.find(filter.view());
// 查询选项(排序、分页、投影)
mongocxx::options::find opts;
opts.sort(document{} << "age" << 1 << finalize); // 按 age 升序
opts.limit(10);
opts.skip(20);
opts.projection(document{} << "name" << 1 << "age" << 1 << "_id" << 0 << finalize);
auto cursor3 = coll.find(filter.view(), opts);
// 查询单个
auto one = coll.find_one(document{} << "name" << "Alice" << finalize);
if (one) {
auto name = (*one)["name"].get_string().value;
std::cout << name << "\n";
}
// 统计
auto count = coll.count_documents(document{} << "age" << bsoncxx::builder::stream::open_document
<< "$gt" << 18
<< bsoncxx::builder::stream::close_document
<< finalize);
std::cout << "成年用户: " << count << "\n";更新与删除
cpp
// 更新单个
auto update_filter = document{} << "name" << "Alice" << finalize;
auto update = document{} << "$set" << bsoncxx::builder::stream::open_document
<< "age" << 31
<< "updated" << true
<< bsoncxx::builder::stream::close_document
<< finalize;
coll.update_one(update_filter.view(), update.view());
// 更新多个
auto update_many_filter = document{} << "age" << bsoncxx::builder::stream::open_document
<< "$lt" << 18
<< bsoncxx::builder::stream::close_document
<< finalize;
auto inc_update = document{} << "$inc" << bsoncxx::builder::stream::open_document
<< "age" << 1
<< bsoncxx::builder::stream::close_document
<< finalize;
coll.update_many(update_many_filter.view(), inc_update.view());
// upsert(不存在则插入)
mongocxx::options::update upsert_opts;
upsert_opts.upsert(true);
coll.update_one(update_filter.view(), update.view(), upsert_opts);
// 删除
coll.delete_one(document{} << "name" << "Alice" << finalize);
coll.delete_many(document{} << "age" << bsoncxx::builder::stream::open_document
<< "$lt" << 18
<< bsoncxx::builder::stream::close_document
<< finalize);聚合管道
cpp
// 聚合:按部门统计平均薪资
mongocxx::pipeline pipeline;
pipeline.match(document{} << "active" << true << finalize);
pipeline.group(document{}
<< "_id" << "$department"
<< "avg_salary" << bsoncxx::builder::stream::open_document
<< "$avg" << "$salary"
<< bsoncxx::builder::stream::close_document
<< "count" << bsoncxx::builder::stream::open_document
<< "$sum" << 1
<< bsoncxx::builder::stream::close_document
<< finalize);
pipeline.sort(document{} << "avg_salary" << -1 << finalize);
auto cursor = coll.aggregate(pipeline);
for (const auto& doc : cursor) {
std::cout << bsoncxx::to_json(doc) << "\n";
}索引
cpp
// 创建索引
auto index_spec = document{} << "email" << 1 << finalize;
mongocxx::options::index index_opts;
index_opts.unique(true);
coll.create_index(index_spec.view(), index_opts);
// 复合索引
coll.create_index(document{} << "age" << 1 << "name" << 1 << finalize);
// 文本索引(全文搜索)
coll.create_index(document{} << "description" << "text" << finalize);
auto text_query = document{} << "$text" << bsoncxx::builder::stream::open_document
<< "$search" << "cpp programming"
<< bsoncxx::builder::stream::close_document
<< finalize;
auto text_cursor = coll.find(text_query.view());关键认知
mongocxx 的 BSON builder 语法初看繁琐,但类型安全。bsoncxx::to_json() 和 bsoncxx::from_json() 可以与 JSON 字符串互转,方便调试。聚合管道是 MongoDB 最强大的查询工具,复杂统计优先用聚合而非多次查询。