最近一個項目,使用了MongoDB,c 語言調用 mongo-c-driver 函數實現數據庫的操作,網上資料較少,自己摸索總結了一些方法,做個記錄。
一、查詢
1、函數 mongoc_collection_find_with_opts 和 mongoc_collection_find
如果只有查詢條件,沒有輸出條件,這兩個函數都可使用;如果有輸出條件,則使用mongoc_collection_find_with_opts,結合關鍵字:projection
例子:
query = BCON_NEW("AfileID", FileID);
bson_init(&child3);
BSON_APPEND_DOCUMENT_BEGIN(&child3, "projection", &child);
BSON_APPEND_INT32(&child, "_id", 0);
BSON_APPEND_INT32(&child, "username", 0);
bson_append_document_end(&child3, &child);
cursor = mongoc_collection_find_with_opts(collection_file, query, &child3, NULL);
其中,_id是MongoDB自動添加的id字段, BSON_APPEND_INT32(&child, "_id", 0);中的0,表示不輸出。
2、比較
1)不等於:not eq:
bson_append_document_begin(&child2, "username", -1, &child3);
bson_append_document_begin(&child3, "$not", -1, &child4);
BSON_APPEND_UTF8(&child4, "$eq", m_username);
bson_append_document_end(&child3, &child4);
bson_append_document_end(&child2, &child3);
2)包含:regex (任意位置開始匹配)
bson_append_document_begin(&child2, "userpart", -1, &child3);
BSON_APPEND_UTF8(&child3, "$regex", sstr2.c_str());
bson_append_document_end(&child2, &child3);
regex ^ (從頭開始匹配)
allpath = "^" + sdirold + "\/";
bson_init(&child2);
BSON_APPEND_DOCUMENT_BEGIN(&child2, "where", &child);
BSON_APPEND_UTF8(&child, "$regex", allpath.c_str());
bson_append_document_end(&child2, &child);
3)並且:and
bson_append_array_begin(&query, "$and", -1, &child);
bson_append_document_begin(&child, "0", -1, &child2);
bson_append_document_begin(&child2, "userpart", -1, &child3);
BSON_APPEND_UTF8(&child3, "$regex", sstr2.c_str());
bson_append_document_end(&child2, &child3);
bson_append_document_end(&child, &child2);
bson_append_document_begin(&child, "1", -1, &child2);
bson_append_document_begin(&child2, "username", -1, &child3);
bson_append_document_begin(&child3, "$not", -1, &child4);
BSON_APPEND_UTF8(&child4, "$eq", m_username);
bson_append_document_end(&child3, &child4);
bson_append_document_end(&child2, &child3);
bson_append_document_end(&child, &child2);
bson_append_array_end(&query, &child);
4)或:or
bson_append_array_begin(&query, "$or", -1, &child);
bson_append_document_begin(&child, "0", -1, &child2);
BSON_APPEND_UTF8(&child2, "username", m_username);
bson_append_document_end(&child, &child2);
bson_append_document_begin(&child, "1", -1, &child2);
BSON_APPEND_UTF8(&child2, "shareuser", m_username);
bson_append_document_end(&child, &child2);
bson_append_array_end(&query, &child);
5)(>) 大於 - $gt (<) 小於 - $lt (>=) 大於等於 - $gte (<= ) 小於等於 - $lte
bson_append_document_begin(&child2, "date_time", -1, &child3);
BSON_APPEND_DATE_TIME(&child3, "$gte", mktime(&p1) * 1000);
bson_append_document_end(&child2, &child3);
二、更新
1、mongoc_collection_update (mongoc_collection_t *collection,
mongoc_update_flags_t flags,
const bson_t *selector,
const bson_t *update,
const mongoc_write_concern_t *write_concern,
bson_error_t *error);
其中,flags參數有三種選擇:
typedef enum {
MONGOC_UPDATE_NONE = 0, //默認,只修改第一條匹配上的記錄
MONGOC_UPDATE_UPSERT = 1 << 0, //找到匹配的記錄就修改,找不到就追加一條記錄
MONGOC_UPDATE_MULTI_UPDATE = 1 << 1, //批量更新所有匹配上的記錄
} mongoc_update_flags_t;
2、更新指定字段:set
query = BCON_NEW("AfileID", FileID);
bson_t *docUpDate = bson_new();
docUpDate = BCON_NEW("$set", "{",
"filename", newfile.c_str()/*修改值*/,
"where", newpath.c_str(),
"}");
mongoc_collection_update(collection_file, MONGOC_UPDATE_NONE, query, docUpDate, NULL, &error);
三、字段值爲數組的操作:
1、數組字段的匹配,可以完全參照非數組字段,只要數組中出現了條件匹配值,則命中。
BSON_APPEND_UTF8(&child2, "shareuser", m_username);
其中,shareuser 字段是數組字段。
2、數組元素添加 : addToSet
bson_init(&query2);
BSON_APPEND_INT64(&query2, "hash", pichash);
updatedoc = bson_new();
bson_append_document_begin(updatedoc, "$addToSet", -1, &child);
BSON_APPEND_UTF8(&child, "AfileID", FileID); //AfileID字段值爲數組
bson_append_document_end(updatedoc, &child);
mongoc_collection_update(collectionp, MONGOC_UPDATE_UPSERT, &query2, updatedoc, NULL, &error);
3、數組元素刪除: pull
query2 = BCON_NEW("AfileID", out.c_str());
updatedoc = bson_new();
bson_append_document_begin(updatedoc, "$pull", -1, &child);
BSON_APPEND_UTF8(&child, "AfileID", out.c_str());
bson_append_document_end(updatedoc, &child);
mongoc_collection_update(collection_k, MONGOC_UPDATE_MULTI_UPDATE, query2, updatedoc, NULL, &error);
四、ISODate 類型字段的操作
1、插入:ISODate 類型時間,是1900年1月1日0分0秒,到現在的毫秒數(減掉時區),如果想保存到數據庫中,則:
bson_t *insert ;
time_t timer;
time(&timer);
tm tmNow;
localtime_s(&tmNow, &timer);
bson_error_t error;
insert = bson_new();
BSON_APPEND_DATE_TIME(insert, "date_time", mktime(&tmNow) * 1000);//日期類型field的插入
BSON_APPEND_INT32(insert, "total", totaluser);
BSON_APPEND_INT32(insert, "online", totalonline);
if (!mongoc_collection_insert(collection_on, MONGOC_INSERT_NONE, insert, NULL, &error))
結果如下:
{
"_id" : ObjectId("5dc0c70ace1c000032002a34"),
"date_time" : ISODate("2019-11-05T00:49:14.000Z"),
"total" : 315,
"online" : 1
}
比現在時間少了8小時。
2、比較:查找 p1-p2 時間段內的數據記錄 p1、p2爲 tm 類型變量
bson_init(&query);
bson_append_array_begin(&query, "$and", -1, &child);
bson_append_document_begin(&child, "0", -1, &child2);
bson_append_document_begin(&child2, "date_time", -1, &child3);
BSON_APPEND_DATE_TIME(&child3, "$gte", mktime(&p1) * 1000);
bson_append_document_end(&child2, &child3);
bson_append_document_end(&child, &child2);
bson_append_document_begin(&child, "1", -1, &child2);
bson_append_document_begin(&child2, "date_time", -1, &child3);
BSON_APPEND_DATE_TIME(&child3, "$lte", mktime(&p2) * 1000);
bson_append_document_end(&child2, &child3);
bson_append_document_end(&child, &child2);
bson_append_document_end(&query, &child);
cursor = mongoc_collection_find(collection_on, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, NULL);
3、提取數據庫中 ISODate 類型字段:
實際上,數據庫中的每條記錄,轉換成字符串如下所示:
{ "_id" : { "$oid" : "5deef071a6070000910072a4" }, "date_time" : { "$date" : 1575940209000 }, "total" : 315, "online" : 1 }
date_time字段是一個json結構,提取方法如下:
value2= value["date_time"];
maxontime =(time_t)( value2["$date"].asInt64() /1000);