読者です 読者をやめる 読者になる 読者になる

アプリエンジニアからみたMongo shell プログラミング

この記事はMongoDB Advent Calendar 2015 の記事です

qiita.com

業務でMongoDBを利用しているので、少しでも貢献しようと思い参加させていただきました

記事の内容的には、最近感動したMongo shelについて書きたいと思います!

2013に似たような記事を書かれていることに気づいてしまったため

アプリエンジニア視点で、MongoShellの便利さを書いてみようと思います

Mongo shellって?

Mongodbでは検索クエリだけでなく、javascriptを実行できるshellが用意されている

ドキュメント https://docs.mongodb.org/manual/reference/mongo-shell/

なにができるの?

一般的な使い方

データの検索・更新・削除

db.users.find({_id:1})

よくあるやつです

応用編

ここからがmongoシェルのすごいところ

jsのコードが書けます

var users = [];
db.users.forEach(function(user) {
  users.push(user);
});

var ids = users.map(function(user) { return user.userId });
var messages = [];
db.messages.find({from: ids}).forEach(function(message) {
  messages.push(message);
});

さらに、DBをまたぐこともできます

2系で複数DB構成の場合はかなり便利

var hogeDB = db.getMongo().getDB('hoge');
var hugaDB = db.getMongo().getDB('huga');
hogeDB.users.find();
hugaDB.users.find();

本気出せばすべてのコレクションをドロップすることも可能です(やっちゃだめです)

var collectionNames = db.getCollectionNames();
collectionNames.forEach(function(collectionName) {
  db[collectionName].drop();
});

外部jsファイルの読み込みもできます

(--quiteオプションにより余分な出力を消せます)

mongo sample_db --quite sample.js

バッチでの利用

ユーザーID一覧をだして!!

user.js
 db.users.find().forEach(function(user) { print(user.userId) });

mongo sample_db user.js --quite > user_id.csv

yes sir !

今日登録したユーザーの課金ログ出して!!

purchase.js
  db.users.find({registerDate: {$gt: new Date()}}).forEach(function(users) {
    var ids = users.map(function(user) {
      return user.userId;
    });

    purchases.find({userId: {$in: ids}}).forEach(function(purchase) {
       print(purchase.userId + "," + purchase.orderId + "," + purchase.purchaseTime + "," + purchase.amount);
    });
  });


mongo sample_db purchase.js --quite > purchase.csv

yes sir !

なんてことが簡単にできます!

find結果の参照はcursorなので、多少大きいデータを抜いたところで メモリーがあふれるとかそういう心配はないはずです

バッチ処理にはもってこいですね!

並列処理に関しては、課題がありますが...

ちょっとしたTips

  • SpiderMonkey準拠なのでv8ベースのnodejsとは異なる
    • 今後v8へ置き換わる可能性はあり
    • console.logはprint
  • find結果のforEachはカーソルなので、一回しかforEachかけられない。二回目はundefinedになる
  • サンプルコードはこの辺を参考にすると良いです

いままで、簡単なデータ抽出でも、いちいちjsでバッチ書いて、クライアントでつないで・・・

ってやってたのですが

ここまで自由にデータ操作ができれば、いちいちバッチとか書かなくても全然いいですね!!

さぁ、みなさんもlet's try MongoDB !