mongodb 修改器($inc/$set/$unset/$push/$pop/upsert)
對于文檔的更新除替換外,針對某個(gè)或多個(gè)文檔只需要部分更新可使用原子的更新修改器,能夠高效的進(jìn)行文檔更新。更新修改器是中特殊的鍵,
用來指定復(fù)雜的操作,比如增加、刪除或者調(diào)整鍵,還可能是操作數(shù)組或者內(nèi)嵌文檔。
1.$inc
這個(gè)修改器干什么使的呢?看看下面示例的具體操作后的結(jié)果即可知道。
示例文檔:{"uid":"201203","type":"1",size:10}
> db.b.insert({"uid":"201203","type":"1",size:10}) > db.b.find() { "_id" : ObjectId("5003b6135af21ff428dafbe6"), "uid" : "201203", "type" : "1", "size" : 10 } > db.b.update({"uid" : "201203"},{"$inc":{"size" : 1}}) > db.b.find() { "_id" : ObjectId("5003b6135af21ff428dafbe6"), "uid" : "201203", "type" : "1", "size" : 11 } > db.b.update({"uid" : "201203"},{"$inc":{"size" : 2}}) > db.b.find() { "_id" : ObjectId("5003b6135af21ff428dafbe6"), "uid" : "201203", "type" : "1", "size" : 13 } > db.b.update({"uid" : "201203"},{"$inc":{"size" : -1}}) > db.b.find() { "_id" : ObjectId("5003b6135af21ff428dafbe6"), "uid" : "201203", "type" : "1", "size" : 12 }
得出結(jié)論:修改器$inc可以對文檔的某個(gè)值為數(shù)字型(只能為滿足要求的數(shù)字)的鍵進(jìn)行增減的操作。
(這里有個(gè)問題:上篇中說到更新默認(rèn)只對滿足條件的記錄集中第一個(gè)文檔進(jìn)行更新,那么使用$inc修改器之后,還是一樣嗎?)
2.$set
用來指定一個(gè)鍵并更新鍵值,若鍵不存在并創(chuàng)建。來看看下面的效果:
> db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "num" : 40, "sname" : "jk", "type" : "3", "uid" : "20120002" } --size鍵不存在的場合 > db.a.update({"uid" : "20120002","type" : "3"},{"$set":{"size":10}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "num" : 40, "size" : 10, "sname" : "jk", "type" : "3", "uid" : "20120002" } --sname鍵存在的場合 > db.a.update({"uid" : "20120002","type" : "3"},{"$set":{"sname":"ssk"}}) > db.a.find() { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "num" : 40, "size" : 10, "sname" : "ssk", "type" : "3", "uid" : "20120002" } { "_id" : ObjectId("50026affdeb4fa8d154f8572"), "desc" : "hello world1!", "num" : 50, "sname" : "jk", "type" : "1", "uid" : "20120002" } --可改變鍵的值類型 > db.a.update({"uid" : "20120002","type" : "3"},{"$set":{"sname":["Java",".net","c++"]}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "num" : 40, "size" : 10, "sname" : [ "java", ".net", "c++" ], "type" : "3", "uid" : "20120002" }
對于內(nèi)嵌的文檔,$set又是如何進(jìn)行更新的內(nèi)嵌的文檔的呢,請看下面的示例:
示例文檔:{"name":"toyota","type":"suv","size":{"height":10,"width":5,"length":15}}
> db.c.findOne({"name":"toyota"}) { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "type" : "suv", "size" : { "height" : 10, "width" : 5, "length" : 15 } } > db.c.update({"name":"toyota"},{"$set":{"size.height":8}}) > db.c.findOne({"name":"toyota"}) { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 5, "length" : 15 } } > db.c.update({"name":"toyota"},{"$set":{"size.width":7}}) > db.c.findOne({"name":"toyota"}) { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 7, "length" : 15 } }
可見:對于內(nèi)嵌文檔在使用$set更新時(shí),使用"."連接的方式。
3.$unset
從字面就可以看出其意義,主要是用來刪除鍵。
示例操作效果如下:
> db.a.update({"uid" : "20120002","type" : "3"},{"$unset":{"sname":1}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "num" : 40, "size" : 10, "type" : "3", "uid" : "20120002" } > db.a.update({"uid" : "20120002","type" : "3"},{"$unset":{"num":0}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "size" : 10, "type" : "3", "uid" : "20120002" } > db.a.update({"uid" : "20120002","type" : "3"},{"$unset":{"size":-1}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "desc" : "hello world2!", "type" : "3", "uid" : "20120002" } > db.a.update({"uid" : "20120002","type" : "3"},{"$unset":{"desc":"sssssss"}}) > db.a.findOne({"uid" : "20120002","type" : "3"}) { "_id" : ObjectId("500216de81b954b6161a7d8f"), "type" : "3", "uid" : "20120002" }
得出結(jié)論:使用修改器$unset時(shí),不論對目標(biāo)鍵使用1、0、-1或者具體的字符串等都是可以刪除該目標(biāo)鍵。
4.數(shù)組修改器--$push
示例操作效果如下:
> db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "type" : "suv", "size" : { "height" : 8, "width" : 7, "length" : 15 } } --先push一個(gè)當(dāng)前文檔中不存在的鍵title > db.c.update({"name" : "toyota"},{$push:{"title":"t1"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1" ], "type" : "suv" } --再向title中push一個(gè)值 > db.c.update({"name" : "toyota"},{$push:{"title":"t2"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2" ], "type" : "suv" } --再向title中push一個(gè)值 > db.c.update({"name" : "toyota"},{$push:{"title":"t2"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2" ], "type" : "suv" } --再向一個(gè)已經(jīng)存在的鍵值非數(shù)組類型的鍵push一個(gè)值 > db.c.update({"name" : "toyota"},{$push:{"size.height":10}}) Cannot apply $push/$pushAll modifier to non-array > db.c.update({"name" : "toyota"},{$push:{"name":"ddddddd"}}) Cannot apply $push/$pushAll modifier to non-array
得出結(jié)論:$push--向文檔的某個(gè)數(shù)組類型的鍵添加一個(gè)數(shù)組元素,不過濾重復(fù)的數(shù)據(jù)。添加時(shí)鍵存在,要求鍵值類型必須是數(shù)組;鍵不存在,則創(chuàng)建數(shù)組類型的鍵。
5.數(shù)組修改器--$ne/$addToSet
主要給數(shù)組類型鍵值添加一個(gè)元素時(shí),避免在數(shù)組中產(chǎn)生重復(fù)數(shù)據(jù),$ne在有些情況是不通行的。
> db.c.update({"title" : {$ne:"t2"}},{$push:{"title":"t2"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2" ], "type" : "suv" } > db.c.update({"name" : "toyota"},{$addToSet:{"title":"t2"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2" ], "type" : "suv" }
6.數(shù)組修改器--$pop、$pull
$pop從數(shù)組的頭或者尾刪除數(shù)組中的元素,示例如下:
{ "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3", "t4" ],"type" : "suv" } --從數(shù)組的尾部刪除 1 > db.c.update({"name" : "toyota"},{$pop:{"title":1}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t3" ], "type" : "suv" } --從數(shù)組的頭部 -1 > db.c.update({"name" : "toyota"},{$pop:{"title":-1}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t2", "t3" ], "type" : "suv" } --從數(shù)組的尾部刪除 0 > db.c.update({"name" : "toyota"},{$pop:{"title":0}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t2" ], "type" : "suv" } $pull從數(shù)組中刪除滿足條件的元素,示例如下: { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t2", "t2", "t3" ],"type" : "suv" } > db.c.update({"name" : "toyota"},{$pull:{"title":"t2"}}) > db.c.find() { "_id" : ObjectId("5003be465af21ff428dafbe7"), "name" : "toyota", "size" : { "height" : 8, "width" : 7, "length" : 15 }, "title" : [ "t1", "t3" ], "type" : "suv" }
7.數(shù)組的定位修改器
在需要對數(shù)組中的值進(jìn)行操作的時(shí)候,可通過位置或者定位操作符("$").數(shù)組是0開始的,可以直接將下標(biāo)作為鍵來選擇元素。
示例如下:
{"uid":"001",comments:[{"name":"t1","size":10},{"name":"t2","size":12}]} > db.c.find({"uid":"001"}) { "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ { "name" : "t1", "size" : 10 }, { "name" : "t2", "size" : 12 } ] } > db.c.update({"uid":"001"},{$inc:{"comments.0.size":1}}) > db.c.find({"uid":"001"}) { "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ { "name" : "t1", "size" : 11 }, { "name" : "t2", "size" : 12 } ] } > db.c.update({"comments.name":"t1"},{$set:{"comments.$.size":1}}) > db.c.find({"uid":"001"}) { "_id" : ObjectId("5003da405af21ff428dafbe8"), "uid" : "001", "comments" : [ { "name" : "t1", "size" : 1 }, { "name" : "t2", "size" : 12 } ] } --若為多個(gè)文檔滿足條件,則只更新第一個(gè)文檔。
8.upsert
upsert是一種特殊的更新。當(dāng)沒有符合條件的文檔,就以這個(gè)條件和更新文檔為基礎(chǔ)創(chuàng)建一個(gè)新的文檔,如果找到匹配的文檔就正常的更新。
使用upsert,既可以避免競態(tài)問題,也可以減少代碼量(update的第三個(gè)參數(shù)就表示這個(gè)upsert,參數(shù)為true時(shí))
> db.c.remove() > db.c.update({"size":11},{$inc:{"size":3}}) > db.c.find() > db.c.update({"size":11},{$inc:{"size":3}},false) > db.c.find() > db.c.update({"size":11},{$inc:{"size":3}},true) > db.c.find() { "_id" : ObjectId("5003ded6c28f67507a6df1de"), "size" : 14 }
9.save函數(shù)
1.可以在文檔不存在的時(shí)候插入,存在的時(shí)候更新,只有一個(gè)參數(shù)文檔。
2.要是文檔含有"_id",會調(diào)用upsert。否則,會調(diào)用插入。
> db.a.find() { "_id" : ObjectId("50026affdeb4fa8d154f8572"), "desc" : "hello world1!", "num": 50, "sname" : "jk", "type" : "1", "uid" : "20120002" } > var o = db.a.findOne() > o.num = 55 55 > db.a.save(o) > db.a.find() { "_id" : ObjectId("50026affdeb4fa8d154f8572"), "desc" : "hello world1!", "num": 55, "sname" : "jk", "type" : "1", "uid" : "20120002" }
相關(guān)文章
MongoDB模糊查詢操作案例詳解(類關(guān)系型數(shù)據(jù)庫的 like 和 not like)
這篇文章主要介紹了MongoDB的模糊查詢操作(類關(guān)系型數(shù)據(jù)庫的 like 和 not like) ,本文通過代碼案例分析給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,,需要的朋友可以參考下2019-07-07centos7安裝mongo數(shù)據(jù)庫的方法(mongo4.2.8)
這篇文章給大家介紹了centos7安裝mongo4.2.8數(shù)據(jù)庫的詳細(xì)過程,包括mongo數(shù)據(jù)庫安裝和啟動方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2022-01-01mongodb 實(shí)現(xiàn)遠(yuǎn)程連接
這篇文章主要介紹了mongodb 實(shí)現(xiàn)遠(yuǎn)程連接,需要的朋友可以參考下2014-07-07MongoDB orm框架的注意事項(xiàng)及簡單使用
MongoDB官方提供的orm的輕量級封裝的 zfoo orm 框架,只對官方提供的進(jìn)行了簡單的封裝,還做了一些官方不支持的語法校驗(yàn)。本文介紹了該框架的注意事項(xiàng)及簡單使用2021-06-06Mongodb聚合函數(shù)count、distinct、group如何實(shí)現(xiàn)數(shù)據(jù)聚合操作
Mongodb中自帶的基本聚合函數(shù)有三種:count、distinct和group。下面我們分別來講述一下這三個(gè)基本聚合函數(shù)及如何實(shí)現(xiàn)數(shù)據(jù)聚合操作,感興趣的朋友一起學(xué)習(xí)吧2016-05-05MongoDB副本集丟失數(shù)據(jù)的測試實(shí)例教程
這篇文章主要給大家介紹了關(guān)于MongoDB副本集丟失數(shù)據(jù)的測試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用MongoDB具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05mongodb添加arbiter節(jié)點(diǎn)的方法示例
這篇文章主要給大家分享了關(guān)于利用mongodb添加arbiter節(jié)點(diǎn)的方法示例,文中給出了詳細(xì)的示例代碼,相信對大家具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-02-02