1、下载mongo-c-driver源码文件:
https://github.com/mongodb/mongo-c-driver.git
2、下载`libbson的源码
https://github.com/mongodb/libbson.git
如果不想编译直接使用可以下载我编译好的文件:
mongo-c-driver-win32-bin.7z
mongo-c-driver-win64-bin.7z
3、编译
cmake -G "Visual Studio 15 2017 Win64" "-DCMAKE_INSTALL_PREFIX=E:\mongodb\build\libbson" "-DCMAKE_BUILD_TYPE=Release"
cmake -G "Visual Studio 15 2017 Win64" "-DCMAKE_INSTALL_PREFIX=E:\mongodb\build\mongo-c-driver" "-DBSON_ROOT_DIR=E:\mongodb\build\libbson" -DCMAKE_BUILD_TYPE=Release
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=E:\mongodb\build\mongo-cxx-driver -DLIBMONGOC_DIR=E:\mongodb\build\mongo-c-driver -DLIBBSON_DIR=E:\mongodb\build\mongo-c-driver -DBOOST_ROOT=E:\boost_1_65_0 -DCMAKE_BUILD_TYPE=Release
msbuild ALL_BUILD.vcxproj # 编译
msbuild INSTALL.vcxproj # 安装
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/your/cxxdriver/prefix
-DLIBMONGOC_DIR=/your/cdriver/prefix
-DLIBBSON_DIR=/your/cdriver/prefix ..
开发:
MongoDB C Driver程序通过mongoc_client_t
提供了一种简便的访问MongoDB的方法( 与集群配置无关的)。
它满足透明地连接到独立的服务器,副本集和分片集群上的需求。一旦建立了连接,数据库和集合的句柄可以通过结构mongoc_database_t
和mongoc_collection_t
分别得到。然后可以通过这些句柄执行MongoDB操作。
在应用程序的启动后,先调用mongoc_init()
,libmongoc 的任何其他功能才能正确使用,并需要在退出之前调用mongoc_cleanup()
。当创建client、database和server的句柄后,需要在使用完后调用适当的销毁函数。
操作例子:
1、初始化mongoc
非线程安全,只需调用一次
mongoc_init();1
2、设置日志回调
static void log_handler (mongoc_log_level_t log_level, const char* log_domain, const char* message, void* user_data)
{
cout << "[mongo][" << log_domain << "]" << message;
}
mongoc_log_set_handler (log_handler, NULL);123456
3、连接mongodb
const char *uristr = "mongodb://127.0.0.1/";
mongoc_client_t* m_pClient = mongoc_client_new(uristr);
//不使用用户名和密码
client = mongoc_client_new("mongodb://root:password@localhost:27017/?authSource=mydb");
//容易看出登录是已uri格式登录的,并可划分成几部分:
//mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]123456
4、获取collection
mongoc_collection_t * m_pCollection = mongoc_client_get_collection(m_pClient, "test_db", "test_collection");1
5、打印bson调试
MongoDB使用了BSON这种结构来存储数据和网络数据交换。 mongoc提供了方法将bson格式转化为json, 可以用于打印调试 。
char* str = bson_as_json(doc, NULL);
fprintf(stdout, "%s\n", str);12
6、插入记录
bson_error_t error;
bson_t *doc = bson_new();
BSON_APPEND_INT64(doc, "id", 1);
BSON_APPEND_INT64(doc, "field1", 0);string msg = "test message";
BSON_APPEND_BINARY(doc, "field2", BSON_SUBTYPE_BINARY, (const uint8_t*)(msg.c_str()), (uint32_t)(msg.size()));
bool r = mongoc_collection_insert(m_pCollection, MONGOC_INSERT_NONE, doc, NULL, &error);if (!r)
{
cout << "Insert Failure:" << error.message;
}
bson_destroy(doc);12345678910111213
7、更新记录
bson_error_t error;
bson_t *doc = bson_new();
bson_t child;
bson_append_document_begin(doc, "$set", -1, &child);
BSON_APPEND_INT64(&child, "field1", 22);
bson_append_document_end(doc, &child);
bson_t query;
bson_init(&query);
BSON_APPEND_INT64(&query, "id", 1);
bool r = mongoc_collection_update(m_pCollection,
MONGOC_UPDATE_NONE,
&query,
doc, NULL,
&error);if (!r)
{
cout << "Update Failure: " << error.message;
}
bson_destroy(&query);
bson_destroy(doc);1234567891011121314151617181920212223
8、删除记录
bson_error_t error;
bson_t query;
bson_init(&query);
BSON_APPEND_INT64(&query, "id", 1);
bool r = mongoc_collection_delete(m_pCollection,
MONGOC_DELETE_NONE,
&query, NULL,
&error);if (!r)
{
cout << "Delete Failure: " << error.message;
ret = ERR_MONGODB_FAILED;
}
bson_destroy(&query);123456789101112131415
9、查询样例:
bson_t query;
bson_t child;
bson_init(&query);
BSON_APPEND_INT64(&query, "id", 0);
mongoc_cursor_t m_pCursor = mongoc_collection_find(m_pCollection,
MONGOC_QUERY_NONE, 0, 0, 0,
&query, NULL, /* Fields, NULL for all. */ NULL); /* Read Prefs, NULL for default */
bson_destroy(&query);
bson_error_t error;if (mongoc_cursor_error(m_pCursor, &error)) {
cout << "Query Failure: " << error.message;
return;
}const bson_t *doc;while (!mongoc_cursor_error(m_pCursor, &error)
&& mongoc_cursor_more(m_pCursor))
{ if (mongoc_cursor_next(m_pCursor, &doc))
{
GetRecord(doc);
} else
{
break;
}
}if (mongoc_cursor_error(m_pCursor, &error)) {
cout << "Query Failure: " << error.message;
}
mongoc_cursor_destroy(m_pCursor);1234567891011121314151617181920212223242526272829303132333435363738394041
10、获取记录
void GetRecord(const bson_t *doc)
{
bson_iter_t iter;
bson_iter_init(&iter, doc); if (bson_iter_find(&iter, "id"))
{ cout << bson_iter_int64(&iter) << "|";
} if (bson_iter_find(&iter, "field1"))
{ cout << bson_iter_int64(&iter) << "|";
} if (bson_iter_find(&iter, "field2"))
{ const uint8_t *binary = NULL;
bson_subtype_t subtype = BSON_SUBTYPE_BINARY;
uint32_t binary_len = 0;
bson_iter_binary(&iter, &subtype, &binary_len, &binary); string msg;
msg.assign((const char*)binary, binary_len); cout << msg << endl;
}
}1234567891011121314151617181920212223242526
11、复杂的or查询和比较查询
//id==4 or field1 <= 12bson_t query;
bson_t child, child2, child3;
bson_init(&query);
bson_append_array_begin(&query, "$or", -1, &child);//0: 第一个or部分bson_append_document_begin(&child, "0", -1, &child2);
BSON_APPEND_INT64(&child2, "id", 4);
bson_append_document_end(&child, &child2);//1:第二个or部分bson_append_document_begin(&child, "1", -1, &child2);//field1 <= 12bson_append_document_begin(&child2, "field1", -1, &child3);
BSON_APPEND_INT64(&child3, "$lte", 12);
bson_append_document_end(&child2, &child3);
bson_append_document_end(&child, &child2);
bson_append_array_end(&query, &child);char * str = bson_as_json(&query, NULL);
printf("\n%s\n", str);12345678910111213141516171819202122232425
12、实现自增ID
nt64_t GetID()
{
int64_t ret = -1;
mongoc_collection_t *pCountCollection = mongoc_client_get_collection(m_pClient, "test_db", "id_generator");
bson_error_t error;
bson_t *doc = bson_new();
bson_t child;
bson_append_document_begin(doc, "$inc", -1, &child);
BSON_APPEND_INT64(&child, "current_id_value", 1);
bson_append_document_end(doc, &child);
bson_t query;
bson_init(&query);
BSON_APPEND_INT64(&query, "_id", 1);
bson_t reply;
bool r = mongoc_collection_find_and_modify(pCountCollection,
&query, NULL,
doc, NULL, false, true, true,
&reply,
&error); if (!r)
{
cout << "GetID Failure: " << error.message;
} else
{
bson_iter_t iter;
bson_iter_init(&iter, &reply); if (bson_iter_find(&iter, "value"))
{ const uint8_t *buf;
uint32_t len;
bson_iter_document(&iter, &len, &buf);
bson_t rec;
bson_init_static(&rec, buf, len);
bson_iter_init(&iter, &rec); if (bson_iter_find(&iter, "current_id_value"))
{
ret = bson_iter_int64(&iter);
}
bson_destroy(&rec);
}
}
bson_destroy(&query);
bson_destroy(&reply);
bson_destroy(doc);
return ret;
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
为了实现自增ID,,需要引入专门计算id的Collection。
该collection中存放的记录格式类似如下:
{‘_id’: 1, ‘current_id_value’:1} ,
其中current_id_value对应着当前最大id值+1,每次需要获取一个ID时,需要先到该collection查询对应的currentIdValue 值并把这个值+1
mongodb提供了findAndModify接口,并且是线程安全的,做到查询并加1的原子操作。