MongoDB
基于CRUD(create,read,update,delete)方式实现了对集合上的文档进行增删改查。对于集合上字段的增删改,可使用set或者unset修改器来实现。也可使用文档替换的方式来实现。本文主要描述集合上字段的增删改,以及基于选项upsert的更新。php
关于MongoDB文档更新能够参考:MongoDB 文档更新mysql
1、语法描述sql
db.collection.update( <query>, //查询或过滤条件 <update>, //修改器(被修改键及内容) { upsert: <boolean>, //为true/false,true时未找到匹配文档则建立新文档 multi: <boolean>, //用于肯定是单行仍是更新全部行(true为全部行) writeConcern: <document> //设定写关注,用于确保强一致性仍是弱一致性 } //后面的3.2以后的语法参数基本相同 ) 其余的如updateOne,updateMany等用法请参考:MongoDB 文档更新 MongoDB集合上全部的写操做特性: 原子性操做(单个文档级别原子性操做) _id 字段没法修改,即没法使用一个新的_id值来代替 因为更新致使文档尺寸超出预期分配的情形,会自动调整填充因子,从新分配空间 保留文档字段的顺序,可是更新或重命名可能致使字段顺序从新排序(_id老是文档第一个字段)
2、update的几个经常使用修改器数组
一、文档更新($set修改器常规更新)markdown
//$set修改器最经常使用,等同于RDBMS update的set子句
//演示重用的的示例集合数据请参考:mongoDB 比较运算符oracle
> 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 } }
二、将文档普通字段转换为数组($set)url
//以下,将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" ] }
三、文档新增字段($set实现)spa
//下面使用$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" }
四、文档删除字段.net
//注,字段的删除方法为{"$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 }
五、字段值的增长或减小code
//当使用$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\"}" } })
六、时间戳字段的增长及自动更新($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")
七、文档字段重命名($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条
3、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 }
4、小结
a、对于文档上数据的修改有多种方式(修改器),经常使用的为$set修改器以及$inc
b、$inc是一种高效的数据修改器,一般用于实现数值的增长或减小,仅支持数据类型。
c、对于文档字段的增长,可使用$set,$unset,$inc,$currentDate等方式
d、对于文档字段的删除,使用$unset方式来实现 e、upsert选项能够实现匹配的文档则更新,不匹配时则插入