《MongoDB》Mongo Shell中的基本操作-更新操作一覽前端博主,熱衷各種前端向的騷操作,經(jīng)常想到哪就寫到哪,如果有感興趣的技術(shù)和前端效果可以留言~博主看到后會(huì)去代替大家踩坑的~
主頁(yè): oliver尹的主頁(yè)
格言: 跌倒了爬起來(lái)就好~
來(lái)個(gè)關(guān)注吧,點(diǎn)個(gè)贊吧,謝謝讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來(lái)自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、雅安服務(wù)器托管、營(yíng)銷軟件、網(wǎng)站建設(shè)、寧江網(wǎng)站維護(hù)、網(wǎng)站推廣。
本篇記錄備份的是Mongo DB的一些基礎(chǔ)知識(shí),包括文檔長(zhǎng)什么樣子,Mongo Shell中的CRUD這四種基本操作,什么是CRUD?C(Creadt、創(chuàng)建)R(Read、讀?。︰(Update、更新)D(Delete、刪除),人話就是增、刪、改、查等等;
注意,本文中的示例命令都是基于Mongo Shell的,并不是直接運(yùn)行在類似于node代碼中的~
本文主要記錄分享了MongoDB中的更新操作以及更新操作時(shí)的操作符
當(dāng)通過insert()方法將文檔在MongoDB中創(chuàng)建之后,肯定是需要對(duì)文檔進(jìn)行更新的,比如用戶點(diǎn)擊了修改密碼,這些操作不是新增,是對(duì)現(xiàn)有數(shù)據(jù)進(jìn)行修改;
3.1 db.collection.update()更新文檔,具體模版如下:
db.update(,,
在不使用 更新操作符 的情況下,使用db.collection.update()將會(huì) 直接替換集合中的文檔;更新操作符等會(huì)再看;
以上方的這個(gè)模版為例,且不使用更新操作符看一個(gè)具體的示例:
db.test.update({name:"oliver"},{name:"oliver",age:20})
簡(jiǎn)單說明:在test這個(gè)集合中找到了name值是oliver的數(shù)據(jù),并且將這條數(shù)據(jù) 替換 成了{(lán)name:“oliver”,age:20},假如這條數(shù)據(jù) 本來(lái)還有其他的字段,這些字段都將會(huì)消失,因?yàn)槭翘鎿Q操作
注意點(diǎn)在更新操作中有一個(gè)需要注意的問題
db.test.update({name:"oliver"},{_id:"demotest",name:"oliver",age:20})
那么 _id這個(gè)值必須和原來(lái)的這個(gè)文檔的_id值保持一致,如果不一致,那么就會(huì)報(bào)錯(cuò),更新失?。?/p>
db.test.update({balance:{$gt:20,$lt:80}},{name:"bill",balance:50,gender:"M"})
在test集合中查詢所有balance大于20,小于80的文檔,將其更新成name等于bill,balance等于50,gender等于M
從結(jié)果看,只有第一篇被更新了,第二篇并沒有被更新,因此說明update的整篇文檔更新只能作用在單一文檔上,這是一個(gè)局限~
使用$set更新某個(gè)字段或者在某個(gè)文檔中創(chuàng)建字段,基本模版如下:
db..update({ $set : {:,...,:} })
具體示例如下
db.test.update(
{name: "jack"},
$set:{
balance: 3000,
info: {
dateOpened: new Date("2016-05-18T16:00:00z")
branch:"branch1"
}
})
首先在update的第一個(gè)參數(shù)name:jack,意思是找到name等于jack的數(shù)據(jù),之后對(duì)這條數(shù)據(jù)進(jìn)行更新,更新的字段是balance和info,將balance的值更新為3000,將info的值更新成一個(gè)對(duì)象,這個(gè)對(duì)象里有一個(gè)branch,且其值是branch1,如果jack這條數(shù)據(jù)不存在balance或者info,那么將為這條數(shù)據(jù)添加這兩個(gè)字段并且加上對(duì)應(yīng)的值;
如果更新的字段是 文檔中的內(nèi)嵌字段,比如上例中info里面的dateOpened,info本身就是一個(gè)對(duì)象,那么更新方式應(yīng)該如下:
db.test.update(
{name: "jack"},
$set:{
"info.dateOpened": new Date("2022-09-18T17:00:00z"),
})
如果更新的字段是 數(shù)組內(nèi)的字段,那么更新方式應(yīng)該如下:
db.test.update(
{name: "jack"},
$set:{
"contact.0": 752746873,
})
contact是一個(gè)數(shù)組,.0代表的就是數(shù)組內(nèi)的下標(biāo),意思就是將contact下的第0位更新成752746873,在數(shù)組內(nèi)新增也是同樣的,為某個(gè)新位置添加對(duì)應(yīng)的值即可,值得注意的是,如果下標(biāo)的位置超出了原本的長(zhǎng)度,比如contact的長(zhǎng)度是3,但現(xiàn)在我們?cè)诘?位添加了數(shù)據(jù),那么第4位就會(huì)自動(dòng)補(bǔ)全為null;
使用$unset刪除文檔中的某個(gè)字段,基本模版如下:
db..update({ $unset : {:"",...,:""} })
具體示例如下
db.test.update(
{name: "jack"},
$unset:{
balance: "",
"info.branch": ""
})
在test集合中找到name等于jack的文檔,刪掉balance這個(gè)字段,同時(shí)也刪掉info這個(gè)對(duì)象下的branch這個(gè)字段;
如果,刪除的字段在文檔中本身就不存在,那么文檔本身將不會(huì)收到任何影響~
如果要 刪除數(shù)組內(nèi)的某個(gè)字段,那么命令應(yīng)該這么寫:
db.test.update(
{name: "jack"},
$unset:{"contact.0": ""})
值得注意的是,刪除內(nèi)容并不會(huì)改變數(shù)組的長(zhǎng)度,只是會(huì)將對(duì)應(yīng)位置的值變成null;
使用$rename重命名文檔中的某個(gè)字段,基本模版如下:
db..update({ $rename : {:,...,:} })
首先要注意的是,如果重命名的字段在文檔中并不存在,那么文檔將不會(huì)有任何改變;如果重命名的字段在文檔中已經(jīng)存在了,那么原來(lái)存在的字段會(huì)被抹去,這個(gè)要非常注意;舉個(gè)例子吧
db.test.update(
{name: "jack"},
$rename:{
name: "contact"
})
contact這個(gè)字段在文檔中本身就已經(jīng)存在了,我們知道這個(gè)字段原來(lái)是一個(gè)數(shù)組,那么如果我們通過rename將name改成contact,那么contact這個(gè)字段原來(lái)值會(huì)被抹去
所以使用時(shí)得非常注意與小心,實(shí)際上,如果我們使用rename已經(jīng)存在的字段,它在內(nèi)部會(huì)先做一個(gè)unset刪除,在做一個(gè)set新增;
如果重命名的字段是 內(nèi)嵌文檔中的字段,那么我們改已以下方式重命名:
db.test.update(
{name: "karen"},
$rename:{
"info.branch": "branch",
"balance":"info.balance"
})
什么意思呢?簡(jiǎn)單的說就是將info.branch路徑的字段重命名成branch,將balance重命名到info下的balance,實(shí)際造成的結(jié)果就有點(diǎn)類似于將字段移動(dòng),
那么 數(shù)組中的字段重命名 呢?
db.test.update(
{name: "karen"},
$rename:{
"contact.3.primaryEmail": "primaryEmail"
})
答案是 不行,MongoDB會(huì)報(bào)錯(cuò),它會(huì)不允許,同理,反向放入數(shù)組也不行,也會(huì)報(bào)錯(cuò)
使用$inc可以更新的某個(gè) 數(shù)字類型的字段值,簡(jiǎn)單的說就是用來(lái)進(jìn)行數(shù)字運(yùn)算,基本模版如下:
db..update({ $inc : {:,...,:} })
看個(gè)例子
db.test.update(
{name: "karen"},
$inc:{
"balance": 0.5
})
得到的結(jié)果就是給name等于karen的文檔下的balance值 加上0.5,同理,如果給的是一個(gè)負(fù)數(shù),如下例
db.test.update(
{name: "karen"},
$inc:{
"balance": -0.5
})
得到的結(jié)果就是給name等于karen的文檔下的balance值 減去0.5;
注意的是,如果操作的字段并 不存在于文檔上,那么字段與字段值會(huì)被作為初始數(shù)據(jù)添加到文檔上,比如"balance"這個(gè)字段不存在文檔上,那么該文檔會(huì)被添加一個(gè)"balance": -0.5的字段;
使用$mul可以更新的某個(gè) 數(shù)字類型的字段值,簡(jiǎn)單的說就是用來(lái)進(jìn)行數(shù)字運(yùn)算,基本模版如下:
db..update({ $mul : {:,...,:} })
看個(gè)例子
db.test.update(
{name: "karen"},
$mul:{
"balance": 2
})
得到的結(jié)果就是給name等于karen的文檔下的balance值 乘以2,同理,如果給的是一個(gè)負(fù)數(shù),如下例
db.test.update(
{name: "karen"},
$mul:{
"balance": 0.5
})
得到的結(jié)果就是給name等于karen的文檔下的balance值 乘以0.5;
注意的是,如果操作的字段并 不存在于文檔上,那么字段與字段值會(huì)被作為初始數(shù)據(jù)添加到文檔上且值和$inc不同,它的值是0,比如"balance"這個(gè)字段不存在文檔上,那么該文檔會(huì)被添加一個(gè)"balance": 0的字段;
使用$min可以更新的某個(gè)字段值,簡(jiǎn)單的說就是用來(lái)進(jìn)行字段比較,小的那一個(gè)會(huì)被最終留下,基本模版如下:
db..update({ $min : {:,...,:} })
看個(gè)例子
db.test.update(
{name: "karen"},
$min:{
"info.balance": 5000
})
意思是,先找到name值等于karen的文檔,然后對(duì)info.balance的值進(jìn)行比較,如果原文檔中的Info.balance值比較小,那么會(huì)保留原來(lái)的值,如果5000比較小,那么會(huì)將info.balance的值更新成5000;
除了數(shù)字類型外,min操作符還可以用在其他類型上,比如時(shí)間,可以比較時(shí)間哪個(gè)小,小的那個(gè)會(huì)被留下, 另外,如果更新的字段不存在,那么$min操作符會(huì)將值初始化進(jìn)文檔;
如果,兩者的類型不一樣,比如 info.balance的值是一個(gè)數(shù)字,我們將其更新成Null,
db.test.update(
{name: "karen"},
$min:{
"info.balance": null
})
最終,文檔的info.balance真的會(huì)被更新成null,因?yàn)樵趍ongodb中它其實(shí)是有一個(gè)內(nèi)部的大小排序的,排序如下
Null< Number< Symbol, String< Object< Array< BinData< ObjectId< Boolean< Date< Timestamp< Regular Expression
由于null比Number要小,因此上面例子中的更新會(huì)將null替換掉數(shù)字;
使用$max可以更新的某個(gè)字段值,簡(jiǎn)單的說就是用來(lái)進(jìn)行字段比較,大的那一個(gè)會(huì)被最終留下,基本模版如下:
db..update({ $max : {:,...,:} })
看個(gè)例子
db.test.update(
{name: "karen"},
$max:{
"info.balance": 5000
})
意思是,先找到name值等于karen的文檔,然后對(duì)info.balance的值進(jìn)行比較,如果原文檔中的Info.balance值比較小,那么會(huì)保留5000,如果5000比較小,那么會(huì)將info.balance的值將不會(huì)變動(dòng),還是保留原來(lái)的值;
除了數(shù)字類型外,min操作符還可以用在其他類型上,比如時(shí)間,可以比較時(shí)間哪個(gè)大,大的那個(gè)會(huì)被留下,另外,如果更新的字段不存在,那么$max操作符會(huì)將值初始化進(jìn)文檔;
如果,兩者的類型不一樣,比如 info.balance的值是一個(gè)數(shù)字,我們將其更新成Null,
db.test.update(
{name: "karen"},
$min:{
"info.balance": null
})
最終,文檔的info.balance會(huì)按規(guī)則進(jìn)行排序,大的那個(gè)將會(huì)被留下,排序如下
Null< Number< Symbol, String< Object< Array< BinData< ObjectId< Boolean< Date< Timestamp< Regular Expression
由于null比Number要小,因此上面例子中的更新將不會(huì)被執(zhí)行,Number依然會(huì)被保留下來(lái);
基本使用方式如下
db..update({ $addToset : {:} })
具體示例如下:
db.test.update(
{name: "jack"},
{$addToset:{contact: "chind"}})
如果添加的值在待添加的數(shù)組中已存在,則會(huì)添加失敗不會(huì)被添加進(jìn)去,但注意的是,如果添加的值是復(fù)雜類型,那么判斷會(huì)比較復(fù)雜,需要值完全相同且順序也完全相同才會(huì)被判定是否已存在數(shù)組中;
$pop 移除元素$pop用來(lái)刪除數(shù)組中的元素,但值得注意的是,只能刪除第一個(gè)元素或者最后一個(gè)元素,基本使用方式如下
db..update({ $pop : {:<1|-1>} })
具體示例如下:
db.test.update(
{name: "jack"},
{$pop:{contact: 1}})
代表刪除contact這個(gè)數(shù)組中最后一個(gè)元素,1代表最后一個(gè),-1代表第一個(gè);
$pull 選擇性刪除基本使用方式如下
db..update({ $pull : {:} })
具體示例如下:
db.test.update(
{name: "jack"},
{$pull:{contact: {$regex:/hi/}}}
)
找到所有name值是jack的文檔,刪除contact中所有包含hi的字段,這里的包含是通過正則進(jìn)行匹配的,另外pull也可以刪除特定的元素,示例如下:
db.test.update(
{name: "jack"},
{$pull:{contact: "222222"}}
)
另外,通過pull去刪除一個(gè)復(fù)雜類型的數(shù)據(jù)時(shí),比如刪除的不再是一個(gè)字符串,而是一個(gè)對(duì)象,通過pull刪除時(shí)只需要提供對(duì)象中的一個(gè)鍵值對(duì)接口刪除整個(gè)數(shù)據(jù),或者提供全量的值但順序可以不一樣,這個(gè)和pullAll不一樣,pullAll需要 全部提供且順序也一樣;
$pullAll 選擇性刪除基本使用方式如下
db..update({ $pullAll : {:[,]} })
具體示例如下:
db.test.update(
{name: "jack"},
{$pullAll:{contact: ['222222','333333']}}
)
找到所有name值是jack的文檔,刪除contact中所有值是222222或者333333的值;
另外,通過pullAll去刪除一個(gè)復(fù)雜類型的數(shù)據(jù)時(shí),比如刪除的不再是一個(gè)字符串,而是一個(gè)對(duì)象,那么參數(shù)必須是順序也是一摸一樣的才會(huì)被刪掉;
基本使用方式如下
db..update({ $push : {:...} })
具體示例如下:
db..update({ $push : {newArray:[1,2,3]} })
這樣[1,2,3]這個(gè)數(shù)組將會(huì)被添加進(jìn)newArray里,如果說想要將1,2,3分別添加進(jìn)行newArray而不是作為一個(gè)整體添加進(jìn)去則需要通過$each操作符
db..update({ $push : {newArray:{$each:[1,2,3]}} })
另外push比addtoset更加強(qiáng)大的地方在于存儲(chǔ)位置的調(diào)整,比如
db..update({ $push : {newArray:{$each:[1,2,3],$position:0}} })
這個(gè)的意思就是說,1,2,3會(huì)被存儲(chǔ)到下標(biāo)為第0位的這個(gè)位置;
還可以進(jìn)行排序,通過 sort 這個(gè)操作符進(jìn)行操作,值得注意的是$sort這個(gè)操作符不可以單獨(dú)使用,必須和 each 操作符一起使用
db..update({ $push : {newArray:{$each:[1,2,3],$sort:1}} })
從小到大進(jìn)行排序,同理,-1則代表從大到小排序;
$slice 操作符代表截取
db..update({ $push : {newArray:{$each:[1,2,3],$slice:-8}} })
代表截取到這數(shù)的8位進(jìn)行保存,對(duì)于剩下的就不再進(jìn)行保存了,直接丟棄,同理,如果值是正數(shù),那么就代表正著數(shù)的8位進(jìn)行保存
如果position,sort,slice被一起使用時(shí),那么順序永遠(yuǎn)是,先通過$position向指定位置進(jìn)行保存,在進(jìn)行排序,最后進(jìn)行截?。?/p>3.4 配置參數(shù)
在上面我們知道,update有三個(gè)參數(shù)
db.update(,,
第三個(gè)參數(shù)中,有幾個(gè)比較重要的配置項(xiàng),首先是multi,是否允許更新多篇文檔
multi 多篇更新{multi:}
具體示例
db.test.update({name:"oliver"},{name:"oliver",age:20},{multi:true})
那么所有的數(shù)據(jù)都將會(huì)被改寫,但值得注意的是,更新多個(gè)文檔的操作雖然在單一線程中執(zhí)行,但是線程在執(zhí)行的過程中可能被掛起,以便其他線程也有機(jī)會(huì)對(duì)數(shù)據(jù)進(jìn)行操作;因此,多個(gè)文檔被操作因此不能保證原子性,也就代表結(jié)果不一定是對(duì)的,比如掛起階段,某個(gè)文檔被其他線程給刪了,那等到掛起的線程繼續(xù)操作時(shí),文檔已經(jīng)改變了,或者干脆已經(jīng)沒有了;
upsert 更新或創(chuàng)建update在沒有匹配到文檔時(shí)是否進(jìn)行創(chuàng)建,默認(rèn)時(shí)不會(huì)進(jìn)行創(chuàng)建的;
{upsert:}
具體示例
db.test.update({name:"oliver"},{name:"oliver",age:20},{upsert:true})
簡(jiǎn)單的說,假如在test中沒有匹配到name為oliver的文檔,此時(shí)會(huì)在test中創(chuàng)建一篇{name:“oliver”,age:20}的文檔
四、小結(jié)本文主要記錄了在常規(guī)數(shù)據(jù)庫(kù)操作中文檔更新的一些用法~更新的命令非常簡(jiǎn)單,都是db.collection.update(),但查詢時(shí)候的操作符非常復(fù)雜,需要經(jīng)常使用與回顧~
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
名稱欄目:《MongoDB》MongoShell中的基本操作-更新操作一覽-創(chuàng)新互聯(lián)
文章轉(zhuǎn)載:http://chinadenli.net/article20/ddijjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、App設(shè)計(jì)、響應(yīng)式網(wǎng)站、網(wǎng)站導(dǎo)航、ChatGPT、網(wǎng)站改版
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容