2019独角兽企业重金招聘Python工程师标准>>>

本文将讨论关于文档中keyvalue为数组的情况如何修改数组。

首先,创建一个c4集合,集合中的文档包含一个arrint字段,值是一个整数数组;一个arrjson字段,值是一个Json对象数组。

> for(i=0;i<5;i++)
2015-03-12T22:06:52.051+0800 SyntaxError: Unexpected end of input
> for(i=0;i<5;i++){
... db.c4.insert({name:"row"+i,arrint:[i+1,i+2,i+3],arrjson:[{name:"j"+i,age:20+i}]})}
WriteResult({ "nInserted" : 1 })
> db.c4.find()
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4c"), "name" : "row1", "arrint" : [ 2, 3, 4 ], "arrjson" : [ { "name" : "j1", "age" : 21 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4d"), "name" : "row2", "arrint" : [ 3, 4, 5 ], "arrjson" : [ { "name" : "j2", "age" : 22 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4e"), "name" : "row3", "arrint" : [ 4, 5, 6 ], "arrjson" : [ { "name" : "j3", "age" : 23 } ] }
{ "_id" : ObjectId("55019e3555c37c4b941feb4f"), "name" : "row4", "arrint" : [ 5, 6, 7 ], "arrjson" : [ { "name" : "j4", "age" : 24 } ] }
>

这里先对整数数组的进行讨论。

要为数组中增加一个整数元素,可以用$push方法。

取出一个数,可以用$pop,将数组字段设置为1则为最后一个元素,-1则为第一个元素。

这里都是栈的形式,都是从数组末尾插入、取出,先进后出。

$push功能:

如果 filed 是一个已经存在的数组,那么把 value 追加给 field;

如果 field 原来不存在,那么新增 field 字段,把 value 的值赋给 field;

如果 field 存在,但是不是一个数组,将会出错;

$push一次只能压入一个值,如果你强行给其多个数,如[11,12]。那么MongoDB会将[11,12]认为是一个独立完整的元素,将[11,12]作为下一个元素整个插入到数组中。

> db.c4.update({name:"row0"},{$push:{arrint:10}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>
> db.c4.update({name:"row0"},{$push:{arrint:[11,12]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10, [ 11, 12 ] ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>
> db.c4.update({name:"row0"},{$pop:{arrint:1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 10 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> db.c4.update({name:"row0"},{$pop:{arrint:1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

如果想压入多个数,需要用到$pushAll:[ ],这里的中括号其实是一个操作符,用来逐一操作多个数。

> db.c4.update({name:"row0"},{$pushAll:{arrint:[13,14]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

如果你像集合那样,希望加入的元素不要有重复,那么请用$addToSet。

功能:

如果 filed 是一个已经存在的数组,并且 value 不在其中,那么把 value 加入到数组;

如果 filed 不存在,那么把 value 当成一个数组形式赋给 field;

如果 field 是一个已经存在的非数组类型,那么将会报错;

> db.c4.update({name:"row0"},{$addToSet:{arrint:14}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.c4.update({name:"row0"},{$addToSet:{arrint:14}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
> db.c4.update({name:"row0"},{$addToSet:{arrint:15}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

相同地,如果要$addToSet多个值也是需要另辟蹊径的。需要与$each配合使用。

> db.c4.update({name:"row0"},{$addToSet:{arrint:{$each:[15,16]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15, 16 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

$pull

语法:

{ $pull : { field : _value } }

功能:

如果 field 是一个数组,那么删除符合_value 检索条件的记录;

如果 field 是一个已经存在的非数组,那么会报错;

$pullAll

语法:

{ $pullAll : { field : value_array } }

功能:

同$push 类似,只是 value 的数据类型是一个数组

> db.c4.update({name:"row0"},{$pull:{arrint:16}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14, 15 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
> db.c4.update({name:"row0"},{$pull:{arrint:{$gte:15}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3, 13, 14 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>
> db.c4.update({name:"row0"},{$pullAll:{arrint:[13,14]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrint" : [ 1, 2, 3 ], "arrjson" : [ { "name" : "j0", "age" : 20 } ] }
>

$rename

语法:

{ $rename : { old_field_name : new_field_name }

功能:

重命名指定的字段名称,从 1.7.2 版本后开始支持

> db.c4.update({name:"row0"},{$rename:{arrint:"arraryInt"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 20 } ], "arraryInt" : [ 1, 2, 3 ] }
>

下面我们进入本文的一个难点,对字段为Json对象数组的修改。

我们先对row0的文档的arrjson字段再添加几个json对象。

> db.c4.update({name:"row0"},{$pushAll:{arrjson:[{name:'j001',age:20},{name:'j0',age:30}]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 20 }, { "name" : "j001", "age" : 20 }, { "name" : "j0", "age" : 30 } ], "arraryInt" : [ 1, 2, 3 ] }
>

现在要将row0文档的arrjson字段数组中第一个name为“j0”的对象的age改为25。

> db.c4.update({name:"row0","arrjson.name":"j0"},{$set:{"arrjson.$.age":25}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.c4.find({name:"row0"})
{ "_id" : ObjectId("55019e3555c37c4b941feb4b"), "name" : "row0", "arrjson" : [ { "name" : "j0", "age" : 25 }, { "name" : "j001", "age" : 20 }, { "name" : "j0", "age" : 30 } ], "arraryInt" : [ 1, 2, 3 ] }
>

特殊操作符:$

$操作符代表查询记录中第一个匹配条件的记录项。

上例中,首先第一个{ }是筛选条件,其中"arrjson.name"选择出arrjson数组中所有name字段为'j0'的json对象。后一个{ }是修改方法,是再前面筛选出来的文档中进行修改,如果用$set:{"arrjson.age":25},无法确定那个子对象是刚才找到的name为'j0'的子对象,所以,这里需要用到$,表示刚才符合第一个匹配条件的那个对象下的age。

转载于:https://my.oschina.net/happyBKs/blog/386419

MongoDB进阶系列(11)——“改”的那些事(二)文档的keyvalue为数组的修改方法...相关推荐

  1. 掌握XML系列(四)---创建格式良好的XML文档

    掌握XML系列(四)---创建格式良好的XML文档 前言:创建良好格式的XML文档,虽然写了这些,其实,等到大家真正的看完之后美酒会发现,其实也很简单的,我们这里所做的是带着大家全面的看看怎么样创建. ...

  2. [译] APT分析报告:11.深入了解Zebrocy的Dropper文档(APT28)

    这是作者新开的一个专栏,主要翻译国外知名安全厂商的APT报告,了解它们的安全技术,学习它们溯源APT组织和恶意代码分析的方法,希望对您有所帮助.当然,由于作者英语有限,会借助机翻进行校验,还请包涵! ...

  3. ehcache springboot_阿里内部进阶学习SpringBoot+Vue全栈开发实战文档

    前言 Spring 作为一个轻量级的容器,在JavaEE开发中得到了广泛的应用,但是Spring 的配置烦琐臃肿,在和各种第三方框架进行整合时代码量都非常大,并且整合的代码大多是重复的,为了使开发者能 ...

  4. 嘴对嘴系列之es核心基础概念之文档和索引

    写在前面 通过之前的几篇安装指南,我们已经把Elasticsearch的集群搭建起来了,并且也使用了Kibana进行交互式的操作.在操作中,我们发现Elasticsearch提供了基于RESTFUL风 ...

  5. linux删除grid数据文件,MongoDB进阶系列(13)——GridFS大文件的添加、获取、查看、删除...

    GridFS是一种在MongoDB中存储大二进制文件的机制,使用GridFS的原因有以下几种: 存储巨大的文件,比如视频.高清图片等. 利用GridFS可以简化需求. GridFS会直接利用已经建立的 ...

  6. 服务器做win7系统改bios设置,Win8系统换装Win7系统bios设置启动修改方法

    在2015年之前上市的很多电脑都是预装了Win8系统,Win8系统对很多人来说操作起来不是那么的习惯.win7系统目前来说还是绝对的桌面系统王者,不管是从使用习惯还是界面的设计Win7绝对是大部分用户 ...

  7. JAVA进阶教学之(源码及API文档概述)

    1.JDK类库的根类:Object 这个从老祖宗类中的方法我们需要先研究一下,因为这些方法都是所有子类通用的. 任何一个类默认继承Object 就算没有直接继承,也会间接继承 2.Object类中有哪 ...

  8. php mongo save,MongoDB:使用save()更新集合中的现有文档

    这些例子没有做同样的事情-- 在JS示例中,您声明了对象mongo > var mongo = db.things.findOne({name:"mongo"}); 然后,您 ...

  9. 极速系列05—python批量拆分/合并PDF文档

    1 python按照页数拆分PDF文档 目的: 将一个PDF文档按照指定的页数拆份额为多个文档 思路: 使用PyPDF库中的PdfFileReader, PdfFileWriter类,这两个类是PyP ...

最新文章

  1. 语音识别框架最新进展——深度全序列卷积神经网络登场
  2. 如何查看oracle版本信息,如何查看oracle版本信息
  3. HDOJ 1247 HDU 1247 Hat’s Words ACM 1247 IN HDU
  4. js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME) 转载...
  5. [转载] python判断字符串中包含某个字符串_干货分享| Python中最常用的字符串方法
  6. Minimum edit distance(levenshtein distance)(最小编辑距离)初探
  7. 格兰杰因果检验_R实现
  8. springcloud服务假死
  9. 零基础使用vscode实现python爬取高德地铁数据
  10. 人工智能全栈学习路线之人工智能概览(百度云智学院学习笔记)
  11. 汉谟塔C语言,巴别塔的故事
  12. Dell_Inspiron_15-3567, 加装内存条, 更换固态硬盘
  13. python大数据培训班学费
  14. js焦点处理的几种方式
  15. 对抗攻击与防御 (1):图像领域的对抗样本生成
  16. 剧情游戏《去月球》随感(待完善)
  17. java定时发送短信_java实现指定时间触发一个事件(比如定时发送短信) | 学步园...
  18. CSS 文字的圆圈背景
  19. Material studio(MS)软件介绍及其应用的领域
  20. An Introduction to Interactive Programming in Python 最后的作业 -- 太空战机

热门文章

  1. MySQL第一篇 (linux ubuntu平台 学习《MySQL技术内幕》总结)
  2. 春天闻香食花——品尝一顿愉悦的花餐
  3. JavaSE核心之一:Date类、Calendar类、Math类、枚举;
  4. HTML5 Canvas 学习日志(三)
  5. 我所经历的大文件数据导出(后台执行,自动生成)
  6. Android Studio 插件的使用
  7. asp.net学习笔记 在GridView中添加链接
  8. vsftp上传文件出现553 Could not create file解决方法
  9. 使用UPnP来穿透NAT使内网接口对外网可见
  10. 在Cisco路由器中配置DHCP服务器