あいつの日誌β

働きながら旅しています。

mongo で $exists を使う例

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

めでたし。