天天看點

c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體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版本) 

c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體

如果覺得這樣麻煩,你也可以直接使用VS2013打開msvc12目錄下的libbson.sln檔案,然後依次生成ALL_BUILD和INSTALL項目。 

如果需要生成32位版本的,也可以在這裡直接建立解決方案平台。 

c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體

編譯後輸出的結果如下圖:

c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體

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     # 安裝
           

編譯後輸出的結果如下圖:

c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體c++操作mongodb Windows 下 mongo-c-driver vs2017編譯 附使用執行個體

操作說明:

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

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:[email protected]:27017/?authSource=mydb");
//容易看出登入是已uri格式登入的,并可劃分成幾部分:
//mongodb://[username:[email protected]]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", );
BSON_APPEND_INT64(doc, "field1", );
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", -, &child);
BSON_APPEND_INT64(&child, "field1", );
bson_append_document_end(doc, &child);

bson_t query;
bson_init(&query);
BSON_APPEND_INT64(&query, "id", );

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

mongoc_cursor_t m_pCursor = mongoc_collection_find(m_pCollection,
    MONGOC_QUERY_NONE,
    ,
    ,
    ,
    &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 = ;
        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", -, &child);

//0: 第一個or部分
bson_append_document_begin(&child, "0", -, &child2);
BSON_APPEND_INT64(&child2, "id", );
bson_append_document_end(&child, &child2);

//1:第二個or部分
bson_append_document_begin(&child, "1", -, &child2);

//field1 <= 12
bson_append_document_begin(&child2, "field1", -, &child3);
BSON_APPEND_INT64(&child3, "$lte", );
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 = -;

    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", -, &child);
    BSON_APPEND_INT64(&child, "current_id_value", );
    bson_append_document_end(doc, &child);

    bson_t query;
    bson_init(&query);
    BSON_APPEND_INT64(&query, "_id", );

    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的原子操作。