18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MongoDB Tips findOrCreate、存在すれば何もせず、存在しなければ insert する

Last updated at Posted at 2013-12-22

タバコを辞めよう辞めようと思って、いまだに禁煙が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" }

追加されていない.
期待通りの結果である.

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?