MongoDB學(xué)習(xí)之路 (五):更新操作符(Update Operators).2nd

本文地址: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 ] }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容