version 2.0.2 のお話です
% mongo --version MongoDB shell version: 2.0.2
仮想の三国志ゲームを例に説明してみる
こんなDocumentをつくっておいて
use test_sangokushi db.dropDatabase(); db.userarea.insert( { _id: 'okamuuu', 'keisyu': 'kanu' }); db.userarea.findOne({_id:'okamuuu'}) { "_id" : "okamuuu", "keisyu" : "kanu" }
関羽を漢中に移動させます。
db.userarea.findAndModify({ query: { _id: "okamuuu", }, update: { $set: { 'kanchu': 'kanu' }, $unset: { 'keisyu': true } }, new: true });
移動完了
{ "_id" : "okamuuu", "kanchu" : "kanu" }
その後益州入りさせます
db.userarea.findAndModify({ query: { _id: "okamuuu", }, update: { $set: { 'ekisyu': 'kanu' }, $unset: { 'kanchu': true } }, new: true });
{ "_id" : "okamuuu", "ekisyu" : "kanu" }
めでたし、といいたいけどこんなクエリ投げてたら問題がおきる、やも。
あれ、関羽が二人いる?
関羽に対して次の命令が来た場合を考えます
で、クエリ投げてみる
db.userarea.findAndModify({ query: { _id: "okamuuu", }, update: { $set: { 'kanchu': 'kanu' }, $unset: { 'ekisyu': true } }, new: true }); db.userarea.findAndModify({ query: { _id: "okamuuu", }, update: { $set: { 'keisyu': 'kanu' }, $unset: { 'ekisyu': true } }, new: true });
OMG!!
{ "_id" : "okamuuu", "kanchu" : "kanu", "keisyu" : "kanu" }
そんなときは$exists
とりあえず関羽を一人に戻しておきます
db.userarea.findAndModify({ query: { _id: "okamuuu", }, update: { $unset: { 'kanchu': true } }, new: true });
{ "_id" : "okamuuu", "keisyu" : "kanu" }
漢中から益州へ移動させようとします。
db.userarea.findAndModify({ query: { _id: "okamuuu", 'kanchu' : { $exists : true } }, update: { $set: { 'ekisyu': 'kanu' }, $unset: { 'kancyu': true } }, new: true });
でもそこには関羽がいないのでヌルっとなりましたとさ。
null
めでたし。