溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MongoDB怎樣處理批量update違反唯一約束的key

發(fā)布時間:2021-11-03 10:36:56 來源:億速云 閱讀:247 作者:柒染 欄目:關(guān)系型數(shù)據(jù)庫

MongoDB怎樣處理批量update違反唯一約束的key,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

        MongoDB批量update一般使用upsert即可,但是這樣更新可能會違反唯一建約束導(dǎo)致全部都沒有更新(關(guān)系型數(shù)據(jù)庫亦是如此),針對這個情況可以一條條更新或者加判斷進(jìn)行更新來保證:不違反唯一約束的行都能得到更新。下面是處理方式,供有需求的人進(jìn)行參考
【背景說明】

  • 集合名:kk_device_likes_game

  • 唯一索引:{"device_id" : 1,

                "target_type" : 1,

                 "target_id" : 1

                }

  • 更新內(nèi)容為:db.kk_device_likes_game.update({"target_type":5,"target_id":NumberLong(1030)},{"$set":{"target_id":NumberLong(1031)}},true,true)

            將滿足條件為"target_type":5,"target_id":NumberLong(1030)的target_id鍵值的NumberLong(1030)改為NumberLong(1031)

        更新會失敗,因為這個集合更新字段上面有復(fù)合唯一索引,使得更新后的鍵值與已有的其他鍵值沖突。這樣導(dǎo)致能被更新的鍵值卻不能更新。報錯如下:

MongoDB怎樣處理批量update違反唯一約束的key

【問題解決】

         針對上面情況:有兩條思路

  • 方式一:遍歷滿足條件集合,逐條更新

            思路:獲取滿足條件的鍵值,遍歷其每一個_id進(jìn)行逐條更新,類似sql為update … where target_type=5 and target_id=1030 and _id =…

           語法如下:

var cursor =  db.kk_device_likes_game.find({"target_type":5,"target_id":NumberLong(1030)})

while  (cursor.hasNext()) {

doc=cursor.next();

a=db.kk_device_likes_game.update({_id:doc._id,"target_type":5,"target_id":NumberLong(1030)},{"$set":{"target_id":NumberLong(1031)}})

print(a)

}

  • 方式二:判斷如果會違反約束就不更新該行

            思路:獲取滿足條件的鍵值,根據(jù)復(fù)合唯一索引{"device_id" : 1,"target_type" : 1,"target_id" : 1},將device_id值跟條件為  target_type=5 and target_id=1031的 device_id進(jìn)行比對,如果有一樣的device_id則該行不更新。類似sql為update …where target_type=5 and target_id=1030 and device_id not in (select device_id from where target_type=5 and target_id=1031 )

           語法如下:

var cursor =  db.kk_device_likes_game.find({"target_type":5,"target_id":NumberLong(1030)})

while  (cursor.hasNext()) {

doc=cursor.next();

a=db.kk_device_likes_game.find({device_id:doc.device_id,"target_type":5,"target_id":NumberLong(1031)}).count()

if ( a == 0 ){

   db.kk_device_likes_game.update({_id:doc._id,"target_type":5,"target_id":NumberLong(1030)},{"$set":{"target_id":NumberLong(1031)}});

  }

else {

   print("_id:" + doc._id + "違反唯一性約束無法更新" );

  }

}

【自我校驗】

         待更新完后,查看滿足更新條件卻沒更新的條目數(shù) 跟 更新后會違反唯一鍵條目數(shù)是否相等,如果相等說明本次更新成功

       查看更新會違反唯一約束的條目數(shù):

i=0

var cursor =  db.kk_device_likes_game.find({"target_type":5,"target_id":NumberLong(1030)})

while  (cursor.hasNext()) {

     doc=cursor.next();

a=db.kk_device_likes_game.find({device_id:doc.device_id,"target_type":5,"target_id":NumberLong(1031)}).count()

i=i+a

}

結(jié)果為431

        查看滿足更新條件卻沒更新的條目數(shù):

db.kk_device_likes_game.find({"target_type":5,"target_id":NumberLong(1030)}).count()

結(jié)果為431

        二者結(jié)果一致,本次更新成功!

看完上述內(nèi)容,你們掌握MongoDB怎樣處理批量update違反唯一約束的key的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI