GridFSの概要
MongoDBに保存できるドキュメントのサイズは、16Mバイトまでという制限があります。一般的なテキストデータを保存するには十分なサイズですが、巨大なテキストデータや動画などのバイナリデータを保存する用途では、16Mバイトを超える場合が出てきます。MongoDBに16Mバイト以上のファイルを保存したい場合、GridFSというインターフェースを使用します。GridFSを使用することにより、データを複数に分割[1]して保存することが可能となります。
今回はMongoDBでサイズの大きなファイルを扱う仕組みである、GridFSについて説明します。
ファイルをデータベースで管理するメリット
ところで、ファイルをデータベースで管理することでどのようなメリットがあるのでしょうか。
多くのシステムでは、画像/音声/動画などサイズの大きなバイナリファイルは、OSのファイルシステムを使って保存されています。ファイルシステムを使用すると慣れ親しんだインターフェースでファイルにアクセスできます。しかし場合によってはファイルをデータベースに保存し、管理した方が効率的なことがあります。以下にデータベースでファイルを管理するメリットを整理してみました。
メタデータの管理がしやすい
ファイルだけではなく、ファイルに関連するメタデータも一緒に管理する場合が多くあります。たとえば、ファイルサイズや作成者、作成日時などです。動画ファイルなら再生回数を管理するケースも考えられます。データベースではファイルと関連したメタデータの管理がしやすく、拡張性があります。また、メタデータを含めたバックアップも容易です。
ファイルシステムの作成数制限を受けない
OS全体でファイル数やディレクトリ数の作成数には制限があります。たとえば、ext3の場合、ディレクトリ内のサブディレクトリやファイルの数は32,000という制限が設定されています。
簡単にGridFSを使ってみる
MongoDBでGridFSを使うのに特別な設定・使用方法は必要ありません。レプリカセット・シャーディングで使用することも可能です。さっそくGridFSを使ってファイルをMongoDBに保存してみましょう。
今回は、MongoDBに標準で用意されているコマンドラインツールであるmongofilesを使用します。コマンドのオプションや詳細は次ページで説明します。
まず、1MB.fileというファイル名で保存するファイルを作成します。下の例ではファイルサイズ1MBで作成しています。
mongofiles[2]を使用して、gridtestというデータベースに先ほど作成した1MB.fileを保存します。
上記のように表示されますと保存成功です。
コレクション構造について
Mongo ShellからGridFSのコレクションを確認してみましょう。MongoDBに接続し、gridtestデータベースを選択します。
コレクションを確認します。
インデックスの他に、fs.chunksとfs.filesというコレクションができています。それぞれの役割は以下のようになっています。
- fs.chunks
GridFSでは、ファイルをチャンクとして一定サイズに分割して、fs.chunksコレクションに保存します。分割するファイルサイズはデフォルトでは256KBです。
- fs.files
fs.filesコレクションには、ファイル名、アップロード日時、MD5ハッシュ情報、ファイルサイズなどのメタデータが保存されています。任意のメタデータを追加することも可能です。
保存されているメタデータに関しては公式ドキュメントにより詳しい情報があります。
次のページでは、GridFSの操作方法としてmongofilesとrubyドライバの2つを説明します。
mongofilesを使ったGridFSの操作
mongofilesはMongoDBに標準で用意されているコマンドラインツールです。MongoDBをインストールしたディレクトリのbin以下にあります。このmongofilesを使って、GridFSを操作してみましょう。
各コマンド共通のコマンドラインオプション
-vオプションは詳細を出力します。
ファイルの追加
ファイルの追加にはputを使います。ここではgridtestデータベースに1MB.fileというファイルを追加します。
同じファイル名で追加しても、上書きされずに別オブジェクトとして追加されます。上書きする場合は、-rオプションを指定してください。
ファイルの取得
ファイルの取得にはgetを使います。
同じファイル名があった場合は、後から追加されたものが取得されます。
ファイルのリスト表示
ファイルをリスト表示するにはlistを使います。ファイル名とファイルサイズが表示されます。同じファイル名がある場合は、複数表示されます。下の例では、1MB.fileという名前のファイルを2つ登録しています。
ファイルの削除
ファイルの削除にはdeleteを使います。
[注意]
同じファイル名のデータはすべて削除されるので注意してください。
ファイルの検索
ファイルの検索にはsearchを使います。指定した文字列がファイル名に含まれている場合は表示されます。
Rubyを使ったGridFSの操作
Ruby用のMongoDB公式ドライバを使用することにより、RubyからGridFSを操作できます。ドライバはgemからインストールできます。
必須ではありませんが、同様にgemでbson_extをインストールするとBSONの処理が高速化されます。
まずは準備を行います。RubyからGridFSを扱うには、fs.chunksにインデックスが作成されている必要があります。mongofilesでファイルを登録することで、自動的にインデックスが作成されます。
以下はgridtestデータベースに対して1MB.fileを保存と取得をし、最後に削除するスクリプトです。ファイル追加時に任意のメタデータを登録できます。
上記をgrid_sample.rbとして保存し、実行します。以下は出力のサンプルです。見やすいように改行を入れています。出力されるfile_idは環境によって変わります。
その他のツール
mongofiles、公式ドライバの他にもGridFSを操作するツールは開発されています。詳細な解説は省略しますが、Nginxから直接GridFSを操作するnginx-gridfsがあります。
次回のテーマ
今回はMongoDBでサイズの大きなファイルを扱うGridFSを紹介いたしました。GridFSを使うことにより、画像や動画などのファイルサイズの大きなデータをMongoDBで管理することができます。
次回はリリース間近となっているMongoDB v2.4の新機能の紹介をする予定です。MongoDB v2.4には全文検索、GeoJSON対応、ハッシュドシャードキーなど先進的な機能が追加されています。お楽しみに!