mongodb c driver bson的嵌套访问与层次结构
使用c訪問mongodb,需要用到mongodb c driver。c++的driver也是基于c driver封裝的。
在使用c driver訪問mongodb時,需要與bson打交道,不過c driver訪問bson有幾點需要注意的,不然會導致報錯,或者找不到數據。
迭代器使用后的有效性
在mongodb c driver中,使用bson_iter_find等操作迭代器后,不要再次使用,有幾點原因:
- 如果api報錯,比如沒找到key,迭代器就會失效,如果繼續用,會導致程序崩潰
- 如果api沒報錯,找到了key,那么下一次繼續使用,查找的value,必須是在當前找到的value后面,如果在迭代器前面,就無法找到。
所以一般操作是在使用迭代器之前,賦值一個局部變量,對這個局部變量進行操作。
官方有如下解釋:
The bson_iter_find() function shall advance iter to the first element named key or exhaust all elements of iter. If iter is exhausted, false is returned and iter should be considered invalid.
示例
const bson_t *doc = nullptr;
bson_iter_t iter;
while (mongoc_cursor_next(cursor, &doc))
{
// 從doc初始化獲得iter
if (!bson_iter_init(&iter, doc))
{
continue;
}
// 創建一個臨時變量的迭代器,用作后續操作
bson_iter_t proiter;
// 把iter賦值給proiter,避免iter失效
proiter = iter;
// 使用proiter進行查找
if (bson_iter_find(&proiter, "key1"))
{
...
}
// 再次把iter賦值給proiter,進行后續操作
proiter = iter;
if (bson_iter_find(&proiter, "key2"))
{
...
}
...
}
子對象與數組遍歷的層次結構
使用mongodb c driver訪問數組結構或者子對象時,也需要注意,其中多了一層,如果少進入一層,就拿不到數據。
數組是結構體
{
"key1": "111",
"key2":
[
{
"ip": "127.0.0.1",
"protocal": "tcp"
},
{
"ip": "127.0.0.2",
"protocal": "udp"
}
]
}
如上,有一個json數據,key1是一個字符串,key2是一個結構體數組,當我們遍歷key2時,其每個元素也是key-value結構,key是數組索引0、1、2...,value才是數組元素。所以進入key2之后,還要再進入一層,才能拿到ip和protocal數據。
示例
// 找到key2,然后遞歸一層,下一層數據的迭代器賦值給sub_iter
if (bson_iter_find(&proiter, "key2") && bson_iter_recurse(&proiter, &sub_iter))
{
// 遍歷sub_iter的所有元素,這里就是上面說的,key是數組的索引,value是ip和protocal結構體
while (bson_iter_next(&sub_iter))
{
bson_iter_t subsubiter;
// 賦值給pproiter局部變量,避免sub_iter失效
bson_iter_t pproiter = sub_iter;
// 再遞歸一層,才能拿到ip和protocal
if (bson_iter_recurse(&pproiter, &subsubiter))
{
bson_iter_t ppproiter = subsubiter;
// 找到ip
if (bson_iter_find(&ppproiter, "ip"))
{
}
}
}
}
數組是value(字符串)
"key1":
{
"ip":
[
"192.168.1.10",
"192.168.1.12",
"192.168.1.13",
"192.168.1.17"
]
}
如果數組是字符串呢?實際上是少了一層,但是也不要忘記,找到數組的迭代器,還是需要遞歸一層才可以拿到數據。
示例
// 找到key1
if (bson_iter_find(&iter, "key1"))
{
// 遞歸一層,獲得key1的下一層ip
bson_iter_recurse(&iter, &subiter);
// 找到ip
if (bson_iter_find(&subiter, "ip"))
{
bson_iter_t piter;
// 遞歸一層,找到ip下一層的數據
bson_iter_recurse(&subiter, &piter);
// 遍歷ip數組內的元素
while(bson_iter_next(&piter))
{
const char *name = bson_iter_utf8 (&piter, NULL);
printf("%s\n", name);
}
}
}
從上面可以看出,mongodb c driver的下一層級的數據遍歷,都是先找到對應的key,再遞歸一層,才能拿到對應的數據。
https://www.mongodb.com/docs/drivers/c/
http://mongoc.org/libbson/current/index.html
http://mongoc.org/
總結
以上是生活随笔為你收集整理的mongodb c driver bson的嵌套访问与层次结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转开源 |Hugo 的使用实践
- 下一篇: 强化学习(四) - 蒙特卡洛方法(Mon