在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 數(shù)據(jù)庫(kù)/ 更新
掌握查詢
簡(jiǎn)介
性能和工具
MongoDB 適用場(chǎng)景
數(shù)據(jù)建模
數(shù)據(jù)聚合
基礎(chǔ)知識(shí)
更新

更新

在第一章,我們介紹了 CRUD 的四分之三(create, read, update 和 delete) 操作。這章,我們來(lái)專(zhuān)門(mén)來(lái)討論我們跳過(guò)的那個(gè)操作: update。 Update 有些獨(dú)特的行為,這是為什么我們把它獨(dú)立成章。

Update: 覆蓋還是 $set

最簡(jiǎn)單的情況, update 有兩個(gè)參數(shù): 選擇器 (where) 和需要更新字段的內(nèi)容。假設(shè) Roooooodles 長(zhǎng)胖了,你會(huì)希望我們這樣操作:

    db.unicorns.update({name: 'Roooooodles'},
        {weight: 590})

(如果你已經(jīng)把 unicorns 集合玩壞了,它已經(jīng)不是原來(lái)的數(shù)據(jù)了的話,再執(zhí)行一次 remove 刪除所有數(shù)據(jù),然后重新插入第一章中所有的代碼。)

現(xiàn)在,如果你查一下被更新了的記錄:

    db.unicorns.find({name: 'Roooooodles'})

你會(huì)發(fā)現(xiàn) update 的第一個(gè)驚喜,沒(méi)找到任何文檔。因?yàn)槲覀冎付ǖ牡诙€(gè)參數(shù)沒(méi)有使用任何的更新選項(xiàng),因此,它 replace 了原始文檔。也就是說(shuō), update 先根據(jù) name 找到一個(gè)文檔,然后用新文檔(第二個(gè)參數(shù))覆蓋替換了整個(gè)文檔。這和 SQL 的 update 命令的完全不一樣。在某些情況下,這非常理想,可以用于某些完全動(dòng)態(tài)更新上。但是,如果你只希望改變一個(gè)或者幾個(gè)字段的值的時(shí)候,你應(yīng)該用 MongoDB 的 $set 操作。繼續(xù),讓我們來(lái)更新重置這個(gè)丟失的數(shù)據(jù):

    db.unicorns.update({weight: 590}, {$set: {
        name: 'Roooooodles',
        dob: new Date(1979, 7, 18, 18, 44),
        loves: ['apple'],
        gender: 'm',
        vampires: 99}})

這里不會(huì)覆蓋新字段 weight 因?yàn)槲覀儧](méi)有指定它。現(xiàn)在讓我們來(lái)執(zhí)行:

    db.unicorns.find({name: 'Roooooodles'})

我們拿到了期待的結(jié)果。因此,在最開(kāi)始的時(shí)候,我們正確的更新 weight 的方式應(yīng)該是:

    db.unicorns.update({name: 'Roooooodles'},
        {$set: {weight: 590}})

Update 操作符

除了 $set,我們還可以用其他的更新操作符做些有意思的事情。所有的更新操作都是對(duì)字段起作用 - 所以你不用擔(dān)心整個(gè)文檔被刪掉。比如,$inc 可以用來(lái)給一個(gè)字段增加一個(gè)正/負(fù)值。假設(shè)說(shuō) Pilot 獲得了非法的兩個(gè) vampire kills 點(diǎn),我們可以這樣修正它:

    db.unicorns.update({name: 'Pilot'},
        {$inc: {vampires: -2}})

假設(shè) Aurora 忽然長(zhǎng)牙了,我們可以給她的 loves 字段加一個(gè)值,通過(guò) $push 操作:

    db.unicorns.update({name: 'Aurora'},
        {$push: {loves: 'sugar'}})

MongoDB 手冊(cè)的 Update Operators 這章,可以查到更多可用的更新操作符的信息。

Upserts

update 還有一個(gè)最大的驚喜,就是它完全支持 upserts。所謂 upsert 更新,即在文檔中找到匹配值時(shí)更新它,無(wú)匹配時(shí)向文檔插入新值,你可以這樣理解。要使用 upsert 我們需要向 update 寫(xiě)入第三個(gè)參數(shù) {upsert:true}

一個(gè)最常見(jiàn)的例子是網(wǎng)站點(diǎn)擊計(jì)數(shù)器。如果我們想保存一個(gè)實(shí)時(shí)點(diǎn)擊總數(shù),我們得先看看是否在頁(yè)面上已經(jīng)有點(diǎn)擊記錄,然后基于此再?zèng)Q定執(zhí)行更新或者插入操作。如果省略 upsert 選項(xiàng)(或者設(shè)為 false),執(zhí)行下面的操作不會(huì)帶來(lái)任何變化:

    db.hits.update({page: 'unicorns'},
        {$inc: {hits: 1}});
    db.hits.find();

但是,如果我們加上 upsert 選項(xiàng),結(jié)果會(huì)大不同:

    db.hits.update({page: 'unicorns'},
        {$inc: {hits: 1}}, {upsert:true});
    db.hits.find();

由于沒(méi)有找到字段 page 值為 unicorns的文檔,一個(gè)新的文檔被生成插入。當(dāng)我們第二次執(zhí)行這句命令的時(shí)候,這個(gè)既存的文檔將會(huì)被更新,且 hits 會(huì)被增加到 2。

    db.hits.update({page: 'unicorns'},
        {$inc: {hits: 1}}, {upsert:true});
    db.hits.find();

批量 Updates

關(guān)于 update 的最后一個(gè)驚喜,默認(rèn)的,它只更新單個(gè)文檔。到目前為止,我們的所有例子,看起來(lái)都挺符合邏輯的。但是,如果你執(zhí)行一些像這樣的操作的時(shí)候:

    db.unicorns.update({},
        {$set: {vaccinated: true }});
    db.unicorns.find({vaccinated: true});

你肯定會(huì)希望,你所有的寶貝獨(dú)角獸都被接種疫苗了。為了達(dá)到這個(gè)目的, multi 選項(xiàng)需要設(shè)為 true:

    db.unicorns.update({},
        {$set: {vaccinated: true }},
        {multi:true});
    db.unicorns.find({vaccinated: true});

小結(jié)

本章中我們介紹了集合的基本 CRUD 操作。我們?cè)敿?xì)講解了 update 及它的三個(gè)有趣的行為。 首先,如果你傳 MongoDB 一個(gè)文檔但是不帶更新操作, MongoDB 的 update 會(huì)默認(rèn)替換現(xiàn)有文檔。因此,你通常要用到 $set 操作 (或者其他各種可用的用于修改文檔的操作)。 其次, update 支持 upsert 操作,當(dāng)你不知道文檔是否存在的時(shí)候,非常有用。 最后,默認(rèn)情況下, update 只更新第一個(gè)匹配文檔,因此當(dāng)你希望更新所有匹配文檔時(shí),你要用 multi 。