MongoDB の update は部分 update ではない
まとめ
- MongoDB の update はレコードのID以外の要素を全て置き換える
- 指定したカラムだけ置き換えてはくれない
- 部分 update したい場合は専用の方法でクエリを作る
MongoDB の update はレコードをほぼ全て置き換える
以下のように insert して update を実行します
db.test.insert({a: 1})
db.test.update({a:1}, {b: 1})
# ruby版
mongo = Mongo::Client.new("mongodb://localhost")
col = mongo[:test]
col.insert_one({ a: 1 })
col.find(a: 1).replace_one({b:1})
insert と update とでキーが違うため、指定した部分だけが書き換わり
{a:1, b:1}
となりそうですが、実際は
{b:1}
と、後のデータで完全上書きされてしまいます。
このように、MongoDB の update はデータの全置き換えを実行します。
なお、ObjectId は変わらないため、消して再度 insert しているのではなく、ObjectId 以外のデータを全て変更しています。
回避方法
もちろん毎度上書きだととても不便なため、回避方法が存在します。
以下のように、update する際に $set
のキーとして変更するデータのみを渡します。
これにより、指定したものだけ書き換えられるようになります。
db.test.update({a:1}, {$set:{b: 1}})
# ruby版
col.insert_one({ a: 1 })
col.find(a: 1).replace_one('$set' => {b:1})