问题描述及测试结果

在使用mongodb时,对一个document中的数组成员进行更新的时候,可以使用$pull $push $pop $addToSet $pullAll$each $position $slice $sort等操作符。

以下问题出现在$addToSetpullAll操作中,$set操作没有这个问题,其他的操作符没有测试,不知道有没有问题。

之前在libmongoc中更新一个对象,用到了这些操作的时候,对于添加进update这个bson对象中的数组成员,其key是没有要求的,大概如下:

// 更新对象的选择
bson_t* selector = BCON_NEW("_id",BCON_OID(_id));
// 更新的内容
bson_t* update = bson_new();
bson_t* each = bson_new();
bson_t array;
bson_append_array_begin(each, "$each", 5, &array);
// 向数组中逐个添加元素,itemArray是要添加的数据保存的数组
for(auto& item:itemArray){
// 以前这里添加的时候,key都使用'0'是没有问题的
bson_append_utf8(&array,"0",1,item.data(),item.size());
}
bson_append_array_end(each, &array);
bson_append_document(update,"$addToSet",9,each);
// 执行更新操作
mongoc_collection_update(
coll, MONGOC_UPDATE_NONE, selector, update, NULL, &error);

这是去年我写代码的时候的做法,这样的操作是一点问题都没有的。当时使用的MongoDB3.4.0版本,使用的libmongoc1.3.1版本。最近一个新项目中再次使用到了MongoDB,这次使用的是4.0.2版本,libmongoc使用的是1.9.3版本。

经过测试(lobmongoc1.9.3),这样的代码在MongoDB 4.0.2版本中,$addToSetpullAll两个有问题,无法实现多个成员的操作。在MongoDB3.4.0中,$addToSet是没有问题的,但是$pullAll也是只能移除一个,不能移除多个。我这里没有测试更多操作,因为只用到了这两个,也没有测1.3.1版本的lobmongoc,因为不能回退到这个版本了。

做如下修改可以完成正常想要的操作

// 更新对象的选择
bson_t* selector = BCON_NEW("_id",BCON_OID(_id));
// 更新的内容
bson_t* update = bson_new();
bson_t* each = bson_new();
bson_t array;
bson_append_array_begin(each, "$each", 5, &array);
// 向数组中逐个添加元素,itemArray是要添加的数据保存的数组
uint32_t i = 0;
for(auto& item:itemArray){
// 以前这里添加的时候,key都使用'0'是没有问题的
// bson_append_utf8(&array,"0",1,item.data(),item.size());
// 不能再使用像上面一样的同一个key,使用下面的形式
char keybuf[16];
const char *key = keybuf;
int keylen = bson_uint32_to_string(i++, &key, keybuf, sizeof(keybuf));
bson_append_utf8(&array,key,keylen,item.data(),item.size());
}
bson_append_array_end(each, &array);
bson_append_document(update,"$addToSet",9,each);
// 执行更新操作
mongoc_collection_update(
coll, MONGOC_UPDATE_NONE, selector, update, NULL, &error);

libmongoc关于\$pullAll和\$addToSet的一个使用问题记录的更多相关文章

  1. mysql中根据一个字段相同记录写递增序号,如序号结果,如何实现?

      mysql中根据一个字段相同记录写递增序号,如序号结果,如何实现? mysql中实现方式如下: select merchantId, NameCn, send_date, deliver_name ...

  2. Oracle 数据库基础学习 (二) 学习小例子:创建一个表,记录商品买卖的情况

      运行环境:Oracle database 11g + PL/SQL Developer ex: --创建一个表 create table plspl_test_product( --加入not n ...

  3. 以Access为支撑,书写一个C#写入记录的案例

    /// <summary> /// 读取Excel文档 /// </summary> /// <param name="Path">文件名称&l ...

  4. cocos2dx 做test遇到一个问题,记录下来

    我新建了一个group,然后再group里面创建一个文件A.h,再A.h中#include group同一级的文件CBaseTest.h,方法是: #include "../BaseTest ...

  5. 用Access作为后台数据库支撑,书写一个C#写入记录的案例

    要想操作一个数据库,不论是那种操作,首先要做的肯定是打开数据库. 下面我们以ACCESS数据库来做例子说明如何打开一个数据库连接!   在这里我们需要用到的是: System.Data.OleDb.O ...

  6. ORACLE 从一个实例迁移到另外一个实例实战记录

    .schema1到schema2的迁移 Oracle 从一个用户expdp导出再impdp导入到还有一个用户,能够使用REMAP_SCHEMA=user1:user2来实现: 假设想导入的用户已经存在 ...

  7. java用毫秒数做日期计算的一个踩坑记录

    错误示例: Date today = new Date(); Date nextMonth = new Date(today.getTime() + 30* 1000*60*60*24); print ...

  8. 部署一个flask服务记录

    最近使用flask写了一些简单的服务. 服务部署到服务器上进行使用,这个过程会有一些问题,需要进行记录一下. 说明运行的环境情况.使用的是python3.6的虚拟环境,系统是centos7,其他的有u ...

  9. my23_pxc其中一个节点重建记录

    PXC报废了一个节点,时间大概在周五,而此时故障的数据库节点比较多,警告信息也成百上千,此信息混合于已有的故障节点信息中,没有被及时发现:然后周六.周日各报废一个,在周一的时候,业务已经没有节点可以写 ...

随机推荐

  1. J 判断二叉树每个结点的权值是否关于根节点完全对称

    如果二叉树每个结点的权值关于根节点完全对称 就输出Yes Sample Input 27 //结点1 2 3 //结点1的左孩子是结点2 右孩子是结点32 4 53 6 74 0 05 0 06 0 ...

  2. spring配置redis注解缓存

    前几天在spring整合Redis的时候使用了手动的方式,也就是可以手动的向redis添加缓存与清除缓存,参考:http://www.cnblogs.com/qlqwjy/p/8562703.html ...

  3. Codeforces Round #321 (Div. 2) E - Kefa and Watch

    题目大意:给你一个由0-9组成的字符串,有m个询问,两种操作,第一种将l到r的字符全部变成c,第二种问l到r这段 字符串的循环节是不是d. 思路:首先我们要知道怎么判断字符串的循环节的长度是不是d,如 ...

  4. Docker 记一次容器内部修改宿主机挂载目录用户权限后宿主机目录变化

    一.需求: 因公司需求,需制作mysql5.7.22 docker基础镜像,每个项目以此镜像启动一个数据库容器,并且每个项目挂载一个宿主机目录到镜像中数据存储下面用于数据持久化保存以便后期迁移至阿里云 ...

  5. POJ 3903 Stock Exchange 【最长上升子序列】模板题

    <题目链接> 题目大意: 裸的DP最长上升子序列,给你一段序列,求其最长上升子序列的长度,n^2的dp朴素算法过不了,这里用的是nlogn的算法,用了二分查找. O(nlogn)算法 #i ...

  6. java中的instanceof用法详解

    instanceof是Java的一个二元操作符(运算符),也是Java的保留关键字.它的作用是判断其左边对象是否为其右边类的实例,返回的是boolean类型的数据.用它来判断某个对象是否是某个Clas ...

  7. Python常用模块--datetime

    datetime是Python专门用于处理日期和时间的标准模块. 1.获取当前的本地时间 #!/usr/bin/env python# -*- coding:utf-8 -*-__author__ = ...

  8. JS高级-原型等概念深入理解

    一 数据类型: 基本(值)数据类型: string number undefined null boolean 对象(引用)类型 [ 查找对象的属性时,会查找原型链 设置属性时,一般在构造函数里面设置 ...

  9. 用js来实现那些数据结构04(栈01-栈的实现)

    其实说到底,在js中栈更像是一种变种的数组,只是没有数组那么多的方法,也没有数组那么灵活.但是栈和队列这两种数据结构比数组更加的高效和可控.而在js中要想模拟栈,依据的主要形式也是数组. 从这篇文章开 ...

  10. 线程、对称多处理和微内核(OS 笔记三)

    线程.对称多处理 ​ 这一部分继续深入探讨与进程管理相关的高级概念并了解多处理机的对称多处理技术. 进程和线程 到目前为止提出的进程的概念包含两个特点: 资源所有权 存放进程映像的虚拟地址空间 调度/ ...