MongoDB怎樣處理批量update違反唯一約束的key,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
MongoDB批量update一般使用upsert即可,但是這樣更新可能會違反唯一建約束導致全部都沒有更新(關系型數據庫亦是如此),針對這個情況可以一條條更新或者加判斷進行更新來保證:不違反唯一約束的行都能得到更新。下面是處理方式,供有需求的人進行參考
【背景說明】
集合名:kk_device_likes_game
唯一索引:{"device_id" : 1,
"target_type" : 1,
"target_id" : 1
}
更新內容為: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)
更新會失敗,因為這個集合更新字段上面有復合唯一索引,使得更新后的鍵值與已有的其他鍵值沖突。這樣導致能被更新的鍵值卻不能更新。報錯如下:

【問題解決】
針對上面情況:有兩條思路
方式一:遍歷滿足條件集合,逐條更新
思路:獲取滿足條件的鍵值,遍歷其每一個_id進行逐條更新,類似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) } |
方式二:判斷如果會違反約束就不更新該行
思路:獲取滿足條件的鍵值,根據復合唯一索引{"device_id" : 1,"target_type" : 1,"target_id" : 1},將device_id值跟條件為 target_type=5 and target_id=1031的 device_id進行比對,如果有一樣的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 + "違反唯一性約束無法更新" ); } } |
【自我校驗】
待更新完后,查看滿足更新條件卻沒更新的條目數 跟 更新后會違反唯一鍵條目數是否相等,如果相等說明本次更新成功
查看更新會違反唯一約束的條目數:
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 } |
結果為431
查看滿足更新條件卻沒更新的條目數:
db.kk_device_likes_game.find({"target_type":5,"target_id":NumberLong(1030)}).count() |
結果為431
二者結果一致,本次更新成功!
看完上述內容,你們掌握MongoDB怎樣處理批量update違反唯一約束的key的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。