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選項能夠實現匹配的文檔則更新,不匹配時則插入