使用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的嵌套访问与层次结构的更多相关文章

  1. MongoDB C Driver使用教程

    MongoDB C Driver使用教程 转载请注明出处http://www.cnblogs.com/oloroso/ 本指南提供简介 MongoDB C 驱动程序. 在 C API 的详细信息,请参 ...

  2. Ignoring Extra Elements in mongoDB C# Driver

    MongoDB删除字段后会报错: Element ... does not match any field or property of class Customer. 需要在实体类增加 [BsonI ...

  3. mongodb .net driver

    1.介绍 The official MongoDB .NET Driver provides asynchronous interaction with MongoDB. Powering the d ...

  4. Mongodb Java Driver 参数配置解析

    要正确使用Mongodb Java Driver,MongoClientOptions参数配置对数据库访问的并发性能影响极大. connectionsPerHost:与目标数据库能够建立的最大conn ...

  5. 给java mongodb 官方driver 增加bean 操作

      mongodb官方的java driver不支持直接插入java bean,只能使用DbObject的Key,Value形式进行insert,update,(c# mongodb官方driver类 ...

  6. MongoDB Java Driver操作指南

    MongoDB为Java提供了非常丰富的API操作,相比关系型数据库,这种NoSQL本身的数据也有点面向对象的意思,所以对于Java来说,Mongo的数据结构更加友好. MongoDB在今年做了一次重 ...

  7. windows平台下安装、编译、使用mongodb C++ driver

    本博客将记录在Win8.1 ,VS2013环境下编译.配置mongodb C++ driver的流程. 1.下载预备 下载Boost:http://sourceforge.net/projects/b ...

  8. mongodb c++ driver(2.53)windows编译

    编译环境: (1) 下载python2.7, 使用x86_32位,因为scons只有32位安装包可用: (2) 下载scons2.3.0,The current production release ...

  9. MongoDB C Driver and APIinstances linux MongoDB安装配置

    <一,linux平台MongoDB安装配置>在这我们使用的Centos6 yum部署的,你想搞编译,自个干!

  10. MongoDB C driver API continues

    开篇前 <1,mongoc_init() func> mongoc_init() Synopsis void mongoc_init (void); Description This fu ...

随机推荐

  1. 如何用 ModelScope 实现 “AI 换脸” 视频

    前言 当下,视频内容火爆,带有争议性或反差大的换脸视频总能吸引人视线.虽然 AI 换脸在市面上已经流行了许久,相关制作工具或移动应用也是数不胜数.但是多数制作工具多数情况下不是会员就是收费,而且替换模 ...

  2. .NET Core多线程 (2) 异步 - 上

    去年换工作时系统复习了一下.NET Core多线程相关专题,学习了一线码农老哥的<.NET 5多线程编程实战>课程,我将复习的知识进行了总结形成本专题. 本篇,我们来复习一下异步的相关知识 ...

  3. 后缀数组C++详解

    后缀定义 "后缀i"代表以第i个字符开头的后缀,存储是用i代表字符串s的后缀s[i...n] 后缀数组是什么? 后缀数组(Suffix Array)主要关系到两个数组:sa 和 r ...

  4. 微服务集成RabbitMq保姆级教程

    本文通过简单的示例代码和说明,让读者能够了解微服务如何集成RabbitMq 之前的教程 https://www.cnblogs.com/leafstar/p/17641358.html 在这里我将介绍 ...

  5. 原神盲盒风格:AI绘画Stable Diffusion原神人物公仔实操:核心tag+lora模型汇总

    本教程收集于:AIGC从入门到精通教程汇总 在这篇文章中,我们将深入探讨原神盲盒的艺术风格,以及如何运用AI绘画技术(Stable Diffusion)--来创造原神角色公仔.我们将通过实践操作让读者 ...

  6. 如何通过API接口获取淘宝的商品评论

    在淘宝网上购买产品时,人们通常会查看其他客户留下的评价和评论.这些评价和评论对于购买决策非常有帮助,因为它们提供了其他客户的观点和建议.通过使用淘宝API接口,可以轻松地获取淘宝上任何商品的评论. 以 ...

  7. (null) entry in command string: null chmod 0644

    在WIndows操作系统中本地运行spark程序,报以下错误: ....(null) entry in command string: null chmod 0644 ..(后面是目的目录) 解决方法 ...

  8. 【matplotlib基础】--文本标注

    Matplotlib 文本和标注可以为数据和图形之间提供额外的信息,帮助观察者更好地理解数据和图形的含义. 文本用于在图形中添加注释或提供更详细的信息,以帮助观察者理解图形的含义.标注则是一种更加细粒 ...

  9. HTML一键打包APK工具1.9.5更新,新增一机一码功能

    HMTL网址打包APK,可以把本地HTML项目, Egret游戏,网页游戏,或者网站打包为一个安卓应用APK文件,无需编写任何代码,也无需配置安卓开发环境,支持在最新的安卓设备上安装运行. 打包软件会 ...

  10. Solution -「九省联考 2018」劈配

    Description Link. 一年一度的综艺节目<中国新代码>又开始了.Zayid 从小就梦想成为一名程序员,他觉得这是一个展示自己的舞台,于是他毫不犹豫地报名了. 轻车熟路的 Za ...