MongoDB 文档字段增删改

                       
 

MongoDB 基于CRUD(create,read,update,delete)方式实现了对集合上的文档进行增删改查。对于集合上字段的增删改,可以使用set set或者unset修改器来实现。也可以使用文档替换的方式来实现。本文主要描述集合上字段的增删改,以及基于选项upsert的更新。

关于MongoDB文档更新可以参考:MongoDB 文档更新

一、语法描述

    db.collection.update(       <query>,                  //查询或过滤条件       <update>,                 //修改器(被修改键及内容)       {                                  upsert: <boolean>,      //为true或者false,如果为true,未找到匹配文档则创建新文档         multi: <boolean>,       //用于确定是单行还是更新所有行(true为所有行)         writeConcern: <document>   //设定写关注,用于确保强一致性还是弱一致性       }                            //后面的3.2之后的语法参数基本相同    )    其他的如updateOne,updateMany等用法请参考:MongoDB 文档更新    MongoDB集合上所有的写操作特性            原子性操作(单个文档级别原子性操作)            _id 字段无法修改,即无法使用一个新的_id值来代替            由于更新导致文档尺寸超出预期分配的情形,会自动调整填充因子,重新分配空间            保留文档字段的顺序,但是更新或重命名可能导致字段顺序重新排序(_id总是文档第一个字段)
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

二、update的几个常用修改器

1、文档更新($set修改器常规更新)

//$set修改器最常用,等同于RDBMS update的set子句
//演示重用的的示例集合数据请参考:mongoDB 比较运算符

> db.persons.find().limit(1).pretty(){        "_id" : ObjectId("5864d8d435ac4f57fb2528f8"),        "name" : "robinson.cheng",        "age" : 25,        "email" : "robinson.cheng@qq.com",        "score" : {                "c" : 89,                "m" : 96,                "e" : 87        },        "country" : "USA",        "books" : [                "JS",                "C++",                "EXTJS",                "MONGODB"        ],        "blog" : "http://blog.csdn.net/leshami"}> > //使用$set修改器修改age字段> db.persons.update({name:"robinson.cheng"},{$set:{age:24}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> //使用$set修改器修改嵌套文档,使用成员.方式来实现> db.persons.update({name:"robinson.cheng"},{$set:{"score.c":92}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> //查看修改后的结果> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,age:1,score:1}).pretty(){        "name" : "robinson.cheng",        "age" : 24,        "score" : {                "c" : 92,                "m" : 96,                "e" : 87        }}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

2、将文档普通字段转换为数组($set)

//如下,将country设定为数组> db.persons.update({name:"robinson.cheng"},{$set:{country:["USA","CN","HK"]}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,country:1}){ "name" : "robinson.cheng", "country" : [ "USA", "CN", "HK" ] }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3、文档新增字段($set实现)

//下面使用$set文档新增一个add字段,也可以使用$inc实现新增字段(见后面的描述)> db.persons.update({name:"robinson.cheng"},{$set:{add:"ShenZhen"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> //查看新增字段add> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,age:1,add:1}){ "name" : "robinson.cheng", "age" : 24, "add" : "ShenZhen" }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4、文档删除字段

//注,字段的删除方法为{"$unset":{field_name:1}}> db.persons.update({name:"robinson.cheng"},{"$unset":{add:1}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//验证删除后的结果add未显示> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,age:1,add:1}){ "name" : "robinson.cheng", "age" : 24 }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

5、字段值的增加或减少

//当使用$inc修改器时,当字段不存在时,会自动创建该字段,如果存在,则在原有值的基础上进行增加或者减少//$inc主要是用于专门进行数字的增加或减少,因此$inc只能用于整型,长整形,或者双精度浮点型的值//$inc不支持字符串,数组以及其他非数字的值//注,对于$inc的操作,$set也可以完成。$inc存在的理由是$inc更高效//下面通过$inc新增salary字段> db.persons.update({name:"robinson.cheng"},{$inc:{salary:1000}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1}).pretty(){ "name" : "robinson.cheng", "salary" : 1000 }//再次执行$inc> db.persons.update({name:"robinson.cheng"},{$inc:{salary:2000}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//查询结果为在原有1000的基础上增加2000,即为3000> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1}).pretty(){ "name" : "robinson.cheng", "salary" : 3000 }//基于$inc的负值> db.persons.update({name:"robinson.cheng"},{$inc:{salary:-1500}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//负值后的结果> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1}).pretty(){ "name" : "robinson.cheng", "salary" : 1500 }//下面使用非数字来实现$inc,报错如下> db.persons.update({name:"robinson.cheng"},{$inc:{salary:"1.5k"}})WriteResult({        "nMatched" : 0,        "nUpserted" : 0,        "nModified" : 0,        "writeError" : {                "code" : 14,                "errmsg" : "Cannot increment with non-numeric argument: {salary: \"1.5k\"}"        }})
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

6、时间戳字段的增加及自动更新($currentDate)

//有时候需要为文档增加最后的更新时间自动,可以使用$currentDate方式来实现//下面为文档增加lastModified时间戳字段> db.persons.update({name:"robinson.cheng"},{$inc:{salary:1000},$currentDate: {lastModified:true}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//查看结果> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1,lastModified:1}){ "name" : "robinson.cheng", "salary" : 2500, "lastModified" : ISODate("2017-02-08T08:23:38.361Z") }//再次更新> db.persons.update({name:"robinson.cheng"},{$inc:{salary:500},$currentDate: {lastModified:true}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })//再次查看结果,时间戳自动被自动更新为最新的时间> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1,lastModified:1}){ "name" : "robinson.cheng", "salary" : 3000, "lastModified" : ISODate("2017-02-08T08:25:26.865Z") }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

7、文档字段重命名($rename)

//下面使用$rename对文档字段重命名> db.persons.update({name:"robinson.cheng"},{$rename:{"name":"ename"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.persons.find({ename:"robinson.cheng"},{"_id":0,ename:1}){ "ename" : "robinson.cheng" }//对子文档字段进行重命名> db.persons.update({ename:"robinson.cheng"},{$rename:{"score.c":"score.chinese"}})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })> db.persons.find({ename:"robinson.cheng"},{"_id":0,ename:1,score:1}){ "score" : { "m" : 96, "e" : 87, "chinese" : 92 }, "ename" : "robinson.cheng" }//对整个集合上所有文档字段进行重命名> db.persons.count()12> db.persons.update({},{$rename:{"name":"ename"}},{multi:true})WriteResult({ "nMatched" : 12, "nUpserted" : 0, "nModified" : 11 }) //此次修改为11条,因为前面以及修改过1
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

三、upsert选项用法

// upsert相当于oracle的merge into或者mysql中的replace into// upsert即是当集合中匹配到满足条件的文档时,则更新文档,否则则是新增文档。前提是该选项的值为true,缺省为flase。> //下面的演示的是匹配到文档时的例子> db.persons.update({name:"robinson.cheng"},{$set:{salary:4000}},{upsert:true})WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })  //此时提示有一个匹配,有一个被更新> db.persons.find({name:"robinson.cheng"},{"_id":0,name:1,salary:1}){ "name" : "robinson.cheng", "salary" : 4000 }> //下面通过upsert方式来新增文档> db.persons.find({name:"thomas"})  //查找thomas> db.persons.update({name:"thomas"},{$set:{salary:4000,country:"USA",age:25}},{upsert:true})WriteResult({        "nMatched" : 0,        "nUpserted" : 1, //此处结果表面有一个upserted,即没有对应得文档,更新的内容作为一个新文档插入到集合        "nModified" : 0,        "_id" : ObjectId("589ae6f4e3a46ff8c567f1bf")})> db.persons.find({name:"thomas"}){ "_id" : ObjectId("589ae6f4e3a46ff8c567f1bf"), "name" : "thomas", "salary" : 4000, "country" : "USA", "age" : 25 }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

四、小结

a、对于文档上数据的修改有多种方式(修改器),常用的为$set修改器以及$inc
b、$inc是一种高效的数据修改器,通常用于实现数值的增加或减少,仅支持数据类型。
c、对于文档字段的增加,可以使用$set,$unset,$inc,$currentDate等方式
d、对于文档字段的删除,使用$unset方式来实现
e、upsert选项可以实现匹配的文档则更新,不匹配时则插入 

DBA牛鹏社(SQL/NOSQL/LINUX)

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值