本文地址:http://www.cnblogs.com/egger/archive/2013/05/01/3053617.html歡迎轉(zhuǎn)載 ,請(qǐng)保留此鏈接??? ????!
通常文檔只會(huì)有一部分要更新。利用原子的更新修改器,可以使得這種部分更新極為髙效。更新修改器是種特殊的鍵,用來(lái)指定復(fù)雜的更新操作,比如調(diào)整、增加或者刪除鍵,還可能是操作數(shù)組或者內(nèi)嵌文檔。
字段更新操作符 Field Update Operators
$set
"$set"用來(lái)指定一個(gè)鍵的值。如果這個(gè)鍵不存在,則創(chuàng)建它。
我們往下面的一條用戶(hù)資料添加“興趣”信息,
db.users.insert({"name":"egger", "age": 28, "sex" : "male"})
運(yùn)行下面的代碼,將該用戶(hù)的興趣設(shè)置為“讀書(shū)”并添加至文檔中(此時(shí)文檔中“hobby”鍵是不存在,該條文檔就會(huì)創(chuàng)建它):
db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},
{"$set" : {"hobby" :"read"}} )
當(dāng)想更改用戶(hù)的興趣資料時(shí),使用"$set" 然后將要更新的內(nèi)容作為鍵“hobby”的值(下面的示例中將數(shù)組作為鍵值):
db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},
{"$set" : {"hobby" :["swimming","basketball"]}} )
用"$set"甚至可以修改鍵的數(shù)據(jù)類(lèi)型
db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$set" : {"sex" :1 }} )
執(zhí)行結(jié)果如下:
使用"$set"修改內(nèi)嵌文檔:
該文檔中的作者信息為內(nèi)嵌文檔,我們將其內(nèi)容全部更改:
db.posts.update({"author.name":"egger"},{"$set":{"author.name":"mongo","author.age":18}})
$unset
從文檔中移除指定的鍵。
若要完全刪除鍵“hobby”,使用“$unset”即可:
db.users.update({"_id" : ObjectId("51826852c75fdd1d8b805801")},{"$unset" : {"hobby" :1 }} )
$inc
"inc"修改器用來(lái)增加已有鍵的值,或者在鍵不存在時(shí)創(chuàng)建一個(gè)鍵。inc"修改器用來(lái)增加已有鍵的值,或者在鍵不存在時(shí)創(chuàng)建一個(gè)鍵。inc就是專(zhuān)門(mén)來(lái)增加(和減少)數(shù)字的。"$inc"只能用于整數(shù)、長(zhǎng)整數(shù)或雙精度浮點(diǎn)數(shù)。要是用在其他類(lèi)型的數(shù)據(jù)上就會(huì)導(dǎo)致操作失敗。
例如毎次有人訪(fǎng)問(wèn)該博文,該條博文的瀏覽數(shù)就加1,用鍵"pageviews"保存瀏覽數(shù)信息。
下面使用"$inc”修改器增加"pageviews"的值
db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")}, {"$inc":{"pageviews":1}})
上面執(zhí)行update時(shí)如果將鍵值設(shè)置為n,那么就表示該鍵的值增加n(n可以為負(fù)數(shù))。
db.posts.update({"_id" : ObjectId("5180f1a991c22a72028238e4")}, {"$inc":{"pageviews":-100}})
$rename
語(yǔ)法: {$rename: { : , : , ... } }
$rename操作符可以重命名字段名稱(chēng),新的字段名稱(chēng)不能和文檔中現(xiàn)有的字段名相同。
如果文檔中存在A(yíng)、B字段,將B字段重命名為A,$rename會(huì)將A字段和值移除掉,然后將B字段名改為A.
集合students中的一條文檔數(shù)據(jù):
{ "_id": 1,"nickname": [ "The American Cincinnatus", "The American Fabius"],"cell": "555-555-5555","name": { "first" : "george", "last" : "washington"}
}
將集合中"nickname"字段名重命名為“alias”、"cell"字段名重命名為"mobile":
db.students.update( { _id: 1 }, { $rename: { 'nickname': 'alias', 'cell': 'mobile' } } )
執(zhí)行下面的更新操作,集合中已存在name字段,將會(huì)刪除“name”字段,將“alias”字段名重命名為“name”
db.students.update( { _id: 1 }, { $rename: { "alias": "name" } } )
當(dāng)重命名子文檔字段名時(shí)需要使用"."操作符,格式:值為該子文檔的字段名.子文檔中字段名。
db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )
執(zhí)行上面的更新操作將name字段的值中first字段重命名為fname.
$rename操作符也可以將子文檔中鍵值移到其他子文檔中。
db.students.update( { _id: 1 }, { $rename: { "name.last": "contact.lname" } } )
我們將名為name的子文檔中的last字段,重名為“l(fā)name”,同時(shí)將其移動(dòng)到子文檔contact中,若contact字段不存在,數(shù)據(jù)庫(kù)會(huì)新建該字段。
若指定的字段在集合中不存在,$rename操作符將不會(huì)有任何影響。
db.students.update( { _id: 1 }, { $rename: { 'wife': 'spouse' } } )
若指定的多個(gè)字段在集合中都不存在,$rename操作符將不會(huì)有任何影響。
db.students.update( { _id: 1 }, { $rename: { 'wife': 'spouse', 'vice': 'vp',? 'office': 'term' } } )
集合中不存在上面語(yǔ)句中指定的wife、vice、office字段,所以上述的更新操作無(wú)任何影響。
若指定的多個(gè)字段中,有的在集合中存在,有的不存在,$rename操作符執(zhí)行下列操作:
存在的字段按照上面的規(guī)則重命名為新的名稱(chēng)。
不存在的字段對(duì)數(shù)據(jù)無(wú)任何影響。
db.students.update( { _id: 1 }, { $rename: { 'wife': 'alias', 'mobile': 'cell' } } )
執(zhí)行上述更新操作,文檔中只有“mobile”字段被替換為“cell”。
upsert
upsert是一種特殊的更新操作,不是一個(gè)操作符。(upsert=up[date]+[in]sert)
update() 方法的三個(gè)參數(shù)是upsert,這個(gè)參數(shù)是個(gè)布爾類(lèi)型,默認(rèn)是false。當(dāng)它為true的時(shí)候,update方法會(huì)首先查找與第一個(gè)參數(shù)匹配的記錄,在用第二個(gè)參數(shù)更新之,如果找不到與第一個(gè)參數(shù)匹配的的記錄,就會(huì)以這個(gè)條件和更新文檔為基礎(chǔ)創(chuàng)建一個(gè)新的文檔。如果找到了匹配的文檔,則正常更新。upsert非常方便,不必預(yù)置集合,同一套代碼可以既創(chuàng)建又更新文檔。
db.users.remove()
db.users.update({age :25}, {$inc :{"age" :3}},true)
db.users.findOne()
我們將users集合清空,執(zhí)行upsert操作,查詢(xún)出age字段值為25的文檔,然后將該字段值增加3.
由于我們先清空了集合,所以u(píng)pdate操作將執(zhí)行insert操作,先創(chuàng)建一個(gè)鍵“age”的值為25的文檔,然后在將這個(gè)值增加3,即鍵“age”的值為28,如圖所示.
$setOnInsert
當(dāng)update方法使用upsert選項(xiàng)執(zhí)行insert操作時(shí),$setOnInsert操作符給相應(yīng)的字段賦值。類(lèi)似sql中update 語(yǔ)句的set。
db.collection.update( ,
{ $setOnInsert: {: , ... } },
{ upsert:true}//{ upsert: true }可以用true替換)
示例:products集合無(wú)任何文檔,執(zhí)行下列語(yǔ)句,將插入一條文檔"{ "_id" : 1, "defaultQty" : 100 }":
db.products.update(
{ _id:1},
{ $setOnInsert: { defaultQty:100} },
{ upsert:true}
)
若update方法執(zhí)行的update操作而不是insert操作,那么$setOnInsert操作符將無(wú)效。
集合中有如下一條文檔:{"_id":1,"defaultQty":100}
下面的update方法將執(zhí)行update操作:
db.products.update(
{ _id:1},
{ $setOnInsert: { defaultQty:500, inStock:true},
$set: { item:"apple"} },
{ upsert:true}
)
更新結(jié)果,$setOnInsert沒(méi)有任何影響。
數(shù)組更新操作符?Array Update Operators
只能用在鍵值為數(shù)組的鍵上的數(shù)組操作。
$ (query)
語(yǔ)法: { ".$" : value }
當(dāng)對(duì)數(shù)組字段進(jìn)行更新時(shí),且沒(méi)有明確指定的元素在數(shù)組中的位置,我們使用定位操作符("$")標(biāo)識(shí)一個(gè)元素,數(shù)字都是以0開(kāi)始的。
和update()一起使用:
定位操作符("$")作為第一個(gè)匹配查詢(xún)條件的元素的占位符,也就是在數(shù)組中的索引值。
數(shù)組字段必須出現(xiàn)查詢(xún)文檔中。
集合students中有兩條文檔:
{ "_id" : 1, "grades" : [ 78, 88, 88] }
{"_id" : 2, "grades" : [ 88, 90, 92 ] }
執(zhí)行下列語(yǔ)句創(chuàng)建集合文檔數(shù)據(jù):
db.students.remove();
db.students.insert({"_id" : 1, "grades" : [ 78, 88, 88] });
db.students.insert({"_id" : 2, "grades" : [ 88, 90, 92 ] });
執(zhí)行下列操作:
//查詢(xún)匹配的文檔中,數(shù)組有2個(gè)88,只更新第一個(gè)匹配的元素,也就是"grades.1"db.students.update( { _id: 1, grades: 88 }, { $set: { "grades.$" : 82} }) ;//查詢(xún)文檔中沒(méi)有出現(xiàn)grades字段,查詢(xún)報(bào)錯(cuò)db.students.update( { _id: 2 }, { $set: { "grades.$" : 82 } } );
"$push"修改器
如果指定的鍵已經(jīng)存在,會(huì)向已有的數(shù)組末尾加入一個(gè)元素,要是沒(méi)有就會(huì)創(chuàng)建一個(gè)新的數(shù)組。
下面是一條文章內(nèi)容的文檔數(shù)據(jù):
我們將使用"$push"對(duì)該文檔添加一條評(píng)論信息。。
db.posts.update({"title":"MongoDB"},{$push:{"comments":{"name":"egger","content":"thks!"}}})
$push 沒(méi)有使用雙引號(hào)。文檔將會(huì)增加一個(gè)"comments"(評(píng)論)鍵且鍵值是數(shù)組類(lèi)型的。
繼續(xù)添加一條評(píng)論信息,該信息將添加至鍵值數(shù)組的末尾。
db.posts.update({"title":"MongoDB"},{$push:{"comments":{"name":"egger","content":"thks 2!"}}})
$pull
語(yǔ)法:db.collection.update( { field: }, { $pull: { field: } } );
pull操作符移除指定字段值為數(shù)組,且匹配pull操作符移除指定字段值為數(shù)組,且匹配pull語(yǔ)句聲明的查詢(xún)條件的所有元素。
//插入一條文檔db.profiles.insert({ votes: [ 3, 5, 6, 7, 7, 8] });//移除數(shù)組中所有元素7db.profiles.update( { votes: 3 }, { $pull: { votes: 7} } );//移除數(shù)組中所有大于6的元素db.profiles.update( { votes: 3 }, { $pull: { votes: { $gt: 6} } } );//Result{ votes: [ 3, 5, 6, 8] }
{ votes: [3, 5, 6 ] }