c++操作mongodb Windows 下 mongo-c-driver vs2017编译 附使用实例

c++操作mongodb Windows 下 mongo-c-driver vs2017编译 附使用实例

转载自:http://blog.csdn.net/weierqiuba/article/details/68923648

侵权请联系我删除。

本文自己进行了简单的注释和资源重连接。

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 

这个windows64 是我编译的 版本mongo_c_driver 1.9.3  原版的,比较旧,我就重新编译了一下。

点击打开链接

https://download.csdn.net/download/x_xx_xxx_xxxx/10353328

 
3、编译libbson

这里先需要使用cmake工具来生成VS2013的项目文件。如果没有安装cmake,请先安装。 
进入mongo-c-driver/src/libbson目录,打开命令行窗口,执行以下命令:

mkdir msvc12        # 建立VS2013项目文件输出路径
cd msvc12           # 进入该路径
cmake -DCMAKE_INSTALL_PREFIX=D:\work_code\mongo-c-driver\usr -G "Visual Studio 12 Win64" ..//如果是VS2017  ,需要 改成// mkdir msvc15// cd msvc15// cmake -DCMAKE_INSTALL_PREFIX=D:\work_code\mongo-c-driver\usr -G "Visual Studio 15 2017 Win64" ..
//注意,上一条语句的最后的两个 “.” 和空格不能省略

上面最后一条命令中的D:\work_code\mongo-c-driver\usr表示的是生成的VS项目中INSTALL.vcxproj这个项目的生成输出路径,也就是libbson编译后的库文件和头文件的输出路径。 
Win64指定项目编译输出的将是64位的库。可以不加此参数,则为32位的库。

注意:CMAKE 工具执行出错一次后,不要在此基础上再修改命令语句进行执行,建议删除新建的文件,重新走一遍。因为我出错后,再执行正确命令,依旧报错,直至删除了mkdir 的目录和文件,重新执行后,才通过,原因不明。

执行完上面的命令后,可以使用如下命令来编译和安装:

msbuild ALL_BUILD.vcxproj   # 编译
msbuild INSTALL.vcxproj     # 安装

上面两个命令需要在VS2013 开发人员命令提示下运行。(默认生成的是Debug版本) 
这里写图片描述

如果觉得这样麻烦,你也可以直接使用VS2013打开msvc12目录下的libbson.sln文件,然后依次生成ALL_BUILD和INSTALL项目。 
如果需要生成32位版本的,也可以在这里直接新建解决方案平台。 
这里写图片描述

编译后输出的结果如下图:

这里写图片描述

4、编译mongo-c-driver

这里的过程和上面差不多。 
先回到mongo-c-driver目录下,执行下面命令:

mkdir msvc12 && cd msvc12
cmake -DCMAKE_INSTALL_PREFIX=D:\work_code\mongo-c-driver\usr -DBSON_ROOT_DIR=D:\work_code\mongo-c-driver\usr  -G "Visual Studio 12 Win64" .. 
//编译环境如果是 VS2017 请改成下面的语句//mkdir msvc15 && cd msvc15//cmake -DCMAKE_INSTALL_PREFIX=D:\work_code\mongo-c-driver\usr -DBSON_ROOT_DIR=D:\work_code\mongo-c-driver\usr  -G "Visual Studio 15 2017 Win64" .. 
  • 1
  • 2

上面的-DBSON_ROOT_DIR=D:\work_code\mongo-c-driver\usr是用于指定libbson库的路径。

注意:CMAKE 工具执行出错一次后,不要在此基础上再修改命令语句进行执行,建议删除新建的文件,重新走一遍。因为我出错后,再执行正确命令,依旧报错,直至删除了mkdir 的目录和文件,重新执行后,才通过,原因不明。


执行如下命令来编译和安装:

//参照 libbson ,只不过在mongo-c-driver(或mongo-c-driver-master)的目录下,新出了一个 mongo-c-driver (或mongo-c-driver-master),在新出现的目录下,执行下列语句

msbuild ALL_BUILD.vcxproj   # 编译
msbuild INSTALL.vcxproj     # 安装

编译后输出的结果如下图:

这里写图片描述

操作说明:

MongoDB C Driver程序通过mongoc_client_t提供了一种简便的访问MongoDB的方法( 与集群配置无关的)。 
它满足透明地连接到独立的服务器,副本集和分片集群上的需求。一旦建立了连接,数据库和集合的句柄可以通过结构mongoc_database_tmongoc_collection_t分别得到。然后可以通过这些句柄执行MongoDB操作。

在应用程序的启动后,先调用mongoc_init(),libmongoc 的任何其他功能才能正确使用,并需要在退出之前调用mongoc_cleanup()。当创建client、database和server的句柄后,需要在使用完后调用适当的销毁函数。

操作例子: 
1、初始化mongoc

非线程安全,只需调用一次

mongoc_init();

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

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]]

4、获取collection

mongoc_collection_t * m_pCollection = mongoc_client_get_collection(m_pClient, "test_db", "test_collection");

5、打印bson调试

MongoDB使用了BSON这种结构来存储数据和网络数据交换。 mongoc提供了方法将bson格式转化为json, 可以用于打印调试 。

char* str = bson_as_json(doc, NULL);
fprintf(stdout, "%s\n", str);

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

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

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

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

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

11、复杂的or查询和比较查询

//id==4 or field1 <= 12
bson_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 <= 12
bson_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);

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

为了实现自增ID,,需要引入专门计算id的Collection。 
该collection中存放的记录格式类似如下: 
{‘_id’: 1, ‘current_id_value’:1} , 
其中current_id_value对应着当前最大id值+1,每次需要获取一个ID时,需要先到该collection查询对应的currentIdValue 值并把这个值+1 
mongodb提供了findAndModify接口,并且是线程安全的,做到查询并加1的原子操作。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值