タバコを辞めよう辞めようと思って、いまだに禁煙が3時間も続かない今日この頃
先日、
「あるドキュメントを探し、既存のドキュメントが存在すれば何もせず、存在しない場合に insert を実行する」
ということをアトミックにやる必要が出てきた。
update コマンドの upsert オプションでできそうだ!
と思ったが無理っぽい。
「あるドキュメントを探し、既存のドキュメントが存在すれば update を行ない、存在しない場合に insert を実行する」
findAndModify というものがあり、これを使えばできそうだ!
ってことで、このコマンドの挙動を調べる。
やりたいこと
「あるドキュメントを探し、既存のドキュメントが存在すれば何もせず、存在しない場合に insert を実行する」
ドキュメント
http://docs.mongodb.org/manual/reference/command/findAndModify/
http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#findandmodify
findAndModify
本家のドキュメントがこちら
http://docs.mongodb.org/manual/reference/command/findAndModify/
オチ
いろいろ、ドキュメント読んでみたが無理そうだった。
そして、英語で「insert if not exists mongodb」とググってみたら、
一発で解決した笑
「insert if not exists mongodb」、「findOrCreate」とかで検索すると良かったみたいです。
$setOnInsert オペレータ
基本的にこのオペレータは, findAndModify、update コマンドと一緒に使用する.
$setOnInsert オペレータにセットした値は、upsert のときだけ更新される.
というシロモノである.
使用例
本の管理用コレクションに例を取ってやってみる.
> show collections;
> db.books.insert({ "name": "basic_of_C++", "price": "200", "num": "20"} );
> db.books.insert({ "name": "basic_of_PHP", "price": "100", "num": "10"} );
> db.books.find();
{ "_id" : ObjectId("52b692c03823dba66d0fcd95"), "name" : "basic_of_C++", "price" : "200", "num" : "20" }
{ "_id" : ObjectId("52b692ce3823dba66d0fcd96"), "name" : "basic_of_PHP", "price" : "100", "num" : "10" }
ここで, basic_of_Perl
という本を追加してみる.
> db.books.update({ "name": "basic_of_Perl" }, { $setOnInsert: {"name": "basic_of_Perl", "price": "100", "num": "10"} }, true, false);
> db.books.find();
{ "_id" : ObjectId("52b692c03823dba66d0fcd95"), "name" : "basic_of_C++", "price" : "200", "num" : "20" }
{ "_id" : ObjectId("52b692ce3823dba66d0fcd96"), "name" : "basic_of_PHP", "price" : "100", "num" : "10" }
{ "_id" : ObjectId("52b6945e626624bd1b04a678"), "name" : "basic_of_Perl", "num" : "10", "price" : "100" }
追加できた.
続いて, もう一度, basic_of_Perl という本を追加してみる.
basic_of_Perl という本は既に存在しているので, 追加されないはずである.
> db.books.update({ "name": "basic_of_Perl" }, { $setOnInsert: {"name": "basic_of_Perl", "price": "100", "num": "100000"} }, true, false);
> db.books.find();
{ "_id" : ObjectId("52b692c03823dba66d0fcd95"), "name" : "basic_of_C++", "price" : "200", "num" : "20" }
{ "_id" : ObjectId("52b692ce3823dba66d0fcd96"), "name" : "basic_of_PHP", "price" : "100", "num" : "10" }
{ "_id" : ObjectId("52b6945e626624bd1b04a678"), "name" : "basic_of_Perl", "num" : "10", "price" : "100" }
追加されていない.
期待通りの結果である.