大きなファイルの保存
項目一覧
Overview
このガイドでは、 GridFSを使用してMongoDBに大容量ファイルを保存、検索する方法を学びます。 GridFSとは、 MongoDB PHPライブラリによって実装された仕様で、ファイルを保存するときにチャンクに分裂し、検索時にファイルを再アセンブルする方法を記述します。 ライブラリのGridFSの実装は、ファイルストレージの操作と組織を管理する抽象化です。
ファイルのサイズがBSONドキュメントサイズ制限の16 MB を超える場合は、 GridFSを使用します。 GridFSがユースケースに適しているかどうかの詳細については、 MongoDB Serverマニュアルの GridFSを参照してください。
GridFS の仕組み
GridFS により、ファイルはバケット(ファイルのチャンクとそれを説明する情報を含む MongoDB コレクションのグループ)に整理されます。 バケットには、GridFS の仕様に定義されている規則を使用して名前付けされた、以下のコレクションが含まれています。
chunks
コレクションには、バイナリ ファイルのチャンクがストアされます。files
コレクションには、ファイルのメタデータがストアされます。
新しいGridFSバケットを作成すると、別の名前を指定しない限り、ライブラリはデフォルトのバケット名fs
を先頭に、前述のコレクションを作成します。 ライブラリは各コレクションにインデックスも作成し、ファイルや関連メタデータを効率的に取得できるようにします。 ライブラリは、 GridFSバケットが存在しない場合は、最初の書込み操作が実行されたときにのみ GridFS バケット を作成します。 ライブラリは、インデックスが存在せず、バケットが空の場合にのみインデックスを作成します。 GridFSインデックスの詳細については、 MongoDB Serverマニュアルの「 GridFSインデックス」を参照してください。
GridFSを使用してファイルを保存する場合、ライブラリはファイルを小さなチャンクに分割し、各ファイルはchunks
コレクションに個別のドキュメントとして表されます。 また、ファイルID、ファイル名、およびその他のファイルメタデータを含むドキュメントをfiles
コレクションに作成します。 MongoDB PHPライブラリにストリームを渡して、新しいストリームを消費または作成し、そのストリームに直接書き込むことで、ファイルをアップロードできます。 ストリームの詳細については、「 ストリーム 」を参照してください。 PHPマニュアルを参照してください。
GridFSがバケットにアップロードされるときにファイルを分割する方法を確認するには、次の図を表示します。
ファイルを検索する際、 GridFSは指定されたバケット内のfiles
コレクションからメタデータを取得し、その情報を使用してchunks
コレクション内のドキュメントからファイルを再構築します。 ファイルの内容を既存のストリームに書き込むか、ファイルをポイントする新しいストリームを作成することで、ファイルを読み取ることができます。
GridFS バケットの作成
GridFSからファイルを保存または検索するには、データベースでMongoDB\Database::selectGridFSBucket()
メソッドを呼び出します。 このメソッドは、既存のバケットにアクセスし、バケットが存在しない場合は新しいバケットを作成します。
次の例では、 db
データベースでselectGridFSBucket()
メソッドを呼び出します。
$bucket = $client->db->selectGridFSBucket();
バケットをカスタマイズする
オプション値を指定する配列をselectGridFSBucket()
メソッドに渡すことで、 GridFSバケット構成をカスタマイズできます。 次の表では、 配列に設定できるオプションの一部を説明しています。
オプション | 説明 |
---|---|
| Specifies the bucket name to use as a prefix for the files and chunks collections.
The default value is 'fs' .Type: string |
| Specifies the chunk size that GridFS splits files into. The default value is 261120 .Type: integer |
| Specifies the read concern to use for bucket operations. The default value is the
database's read concern. Type: MongoDB\Driver\ReadConcern |
| Specifies the read preference to use for bucket operations. The default value is the
database's read preference. Type: MongoDB\Driver\ReadPreference |
| Specifies the write concern to use for bucket operations. The default value is the
database's write concern. Type: MongoDB\Driver\WriteConcern |
次の例では、 bucketName
オプションを設定する配列をselectGridFSBucket()
に渡して、 'myCustomBucket'
という名前のバケットを作成します。
$custom_bucket = $client->db->selectGridFSBucket( ['bucketName' => 'myCustomBucket'] );
ファイルのアップロード
次の方法を使用して、 GridFSバケットにファイルをアップロードできます。
MongoDB\GridFS\Bucket::openUploadStream()
: 新しいアップロードストリームを開き、ファイルの内容を書き込むことができますMongoDB\GridFS\Bucket::uploadFromStream()
: 既存のストリームの内容をGridFSファイルにアップロードします
アップロード ストリームへの書き込み
特定のファイル名のアップロードストリームを作成するには、 openUploadStream()
メソッドを使用します。 openUploadStream()
メソッドを使用すると、オプション配列で構成情報を指定できます。これはパラメーターとして渡すことができます。
この例では、アップロードストリームを使用して次のアクションを実行しています。
次の名称の新しいGridFSファイルの書込み可能なストリームを開きます:
'my_file'
配列パラメータの
metadata
オプションをopenUploadStream()
メソッドに設定しますfwrite()
メソッドを呼び出して'my_file'
にデータを書込み (write) ます。ここではストリームは を指します'my_file'
を指しているストリームを閉じるには、fclose()
メソッドを呼び出します
$stream = $bucket->openUploadStream('my_file', [ 'metadata' => ['contentType' => 'text/plain'] ]); fwrite($stream, 'Data to store'); fclose($stream);
既存のストリームをアップロードする
ストリームの内容を新しいGridFSファイルにアップロードするには、 uploadFromStream()
メソッドを使用します。 uploadFromStream()
メソッドを使用すると、オプション配列で構成情報を指定できます。これはパラメーターとして渡すことができます。
この例では、次のアクションを実行します。
fopen()
メソッドを呼び出して、/path/to/input_file
にあるファイルをバイナリ読み取り(rb
)モードのストリームとして開きますuploadFromStream()
メソッドを呼び出して、ストリームの内容を'new_file'
という名前のGridFSファイルにアップロードします
$file = fopen('/path/to/input_file', 'rb'); $bucket->uploadFromStream('new_file', $file);
ファイル情報の検索
このセクションでは、GridFS バケットの files
コレクションにストアされているファイル メタデータを検索する方法を学びます。メタデータには、参照先のファイルに関する次のような情報が含まれます。
ファイルの
_id
ファイルの名前
ファイルの長さ/サイズ
アップロード日時
その他の情報をストアできる
metadata
ドキュメント
GridFSバケットからファイルを検索するには、 MongoDB\GridFS\Bucket
インスタンスでMongoDB\GridFS\Bucket::find()
メソッドを呼び出します。 このメソッドは、結果にアクセスできるMongoDB\Driver\Cursor
インスタンスを返します。 MongoDB PHPライブラリの Cursor
オブジェクトの詳細については、「カーソルからのデータへのアクセス」ガイドを参照してください。
例
次のコード例は、 GridFSバケット内のファイルからファイルメタデータを検索して印刷する方法を示しています。 foreach
ループを使用して返されたカーソルを反復処理し、 ファイルのアップロード例 にアップロードされたファイルの内容を表示します。
$files = $bucket->find(); foreach ($files as $file_doc) { echo toJSON($file_doc), PHP_EOL; }
{ "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "my_file", "length" : 13, "uploadDate" : { ... }, "metadata" : { "contentType" : "text/plain" }, "md5" : "6b24249b03ea3dd176c5a04f037a658c" } { "_id" : { "$oid" : "..." }, "chunkSize" : 261120, "filename" : "new_file", "length" : 13, "uploadDate" : { ... }, "md5" : "6b24249b03ea3dd176c5a04f037a658c" }
find()
メソッドはさまざまなクエリ仕様を受け入れます。 その$options
パラメーターを使用して、並べ替え順序、返されるドキュメントの最大数、返される前にスキップするドキュメント数を指定できます。 利用可能なオプションのリストを表示するには、 APIドキュメント を参照してください。
注意
上記の例ではtoJSON()
メソッドを呼び出して、次のコードで定義されたファイルメタデータを 拡張JSONとして出力します。
function toJSON(object $document): string { return MongoDB\BSON\Document::fromPHP($document)->toRelaxedExtendedJSON(); }
ファイルのダウンロード
次の方法を使用して、 GridFSバケットからファイルをダウンロードできます。
MongoDB\GridFS\Bucket::openDownloadStreamByName()
またはMongoDB\GridFS\Bucket::openDownloadStream()
: 新しいダウンロードストリームを開き、ファイルの内容を読み取ることができるMongoDB\GridFS\Bucket::downloadToStream()
:ファイル全体を既存のダウンロード ストリームに書き込みます
ダウンロード ストリームからの読み取り
MongoDBデータベースからファイルをダウンロードするには、 MongoDB\GridFS\Bucket::openDownloadStreamByName()
メソッドを使用してダウンロード ストリームを作成します。
この例では、ダウンロード ストリームを使用して次のアクションを実行しています。
アップロードストリームへの書き込みの例でアップロードされた
'my_file'
という名前のGridFSファイルを選択し、読み取り可能なストリームとして開きます'my_file'
の内容を読み取るには、stream_get_contents()
メソッドを呼び出しますファイルの内容を出力します
fclose()
メソッドを呼び出して、 を指しているダウンロード ストリームを閉じます'my_file'
$stream = $bucket->openDownloadStreamByName('my_file'); $contents = stream_get_contents($stream); echo $contents, PHP_EOL; fclose($stream);
"Data to store"
注意
同じファイル名を持つドキュメントが複数ある場合、 GridFSは指定された名前( uploadDate
フィールドによって決定)を持つ最新のファイルをストリーミングします。
あるいは、ファイルの _id
フィールドをパラメータとして受け取る MongoDB\GridFS\Bucket::openDownloadStream()
メソッドを使用することもできます。
$stream = $bucket->openDownloadStream(new ObjectId('66e0a5487c880f844c0a32b1')); $contents = stream_get_contents($stream); fclose($stream);
注意
GridFSストリーミングAPIは部分的なチャンクを読み込むことはできません。 ダウンロード ストリームがMongoDBからチャンクをプルする必要がある場合、チャンク全体をメモリにプルします。 通常、 255キロバイトのデフォルトのチャンク サイズで十分ですが、チャンク サイズを小さくしてメモリのオーバーヘッドを削減したり、大きなファイルを操作する場合はチャンク サイズを増やすことができます。 チャンク サイズの設定の詳細については、このページの「 バケットのカスタマイズ」セクションを参照してください。
ファイルの変更をダウンロード
バケットに同じファイル名を共有する複数のファイルが含まれている場合、 GridFSはデフォルトでファイルの最新アップロード バージョンを選択します。 同じ名前を共有する各ファイルを区別するために、 GridFSはアップロード時間順に、そのファイルにリダイレクト番号を割り当てます。
元のファイルの変更番号は0
で、次の最新のファイルの変更番号は1
です。 変更の直近性に対応する負の値を指定することもできます。 変更値-1
は最新のリビルドを参照し、 -2
は次の最新のリビルドを参照します。
オプション配列をopenDownloadStreamByName()
メソッドに渡し、 revision
オプションを指定することで、 GridFSに特定のファイルリビジョニングをダウンロードするよう指示できます。 次の例では、最新の変更ではなく、 'my_file'
という名前の元のファイルの内容を読み取ります。
$stream = $bucket->openDownloadStreamByName('my_file', ['revision' => 0]); $contents = stream_get_contents($stream); fclose($stream);
既存のストリームへのダウンロード
バケットでMongoDB\GridFS\Bucket::downloadToStream()
メソッドを呼び出すと、 GridFSファイルの内容を既存のストリームにダウンロードできます。
この例では、次のアクションを実行します。
fopen()
メソッドを呼び出して、/path/to/output_file
にあるファイルをバイナリ書込み(wb
)モードのストリームとして開きますストリームに、
_id
値がObjectId('66e0a5487c880f844c0a32b1')
であるGridFSファイルをダウンロードします
$file = fopen('/path/to/output_file', 'wb'); $bucket->downloadToStream( new ObjectId('66e0a5487c880f844c0a32b1'), $file, );
ファイル名の変更
バケット内のGridFSファイルの名前を更新するには、MongoDB\GridFS\Bucket::rename()
メソッドを使用します。次のパラメータを rename()
メソッドに渡します。
_id
名前を変更するファイルの 値新しいファイル名
次の例では、ファイルの _id
値を参照して filename
フィールドを 'new_file_name'
に更新する方法を示します。
$bucket->rename(new ObjectId('66e0a5487c880f844c0a32b1'), 'new_file_name');
または、MongoDB\GridFS\Bucket::renameByName()
メソッドを使用して、 GridFSファイルとそのファイルの変更内容の名前を変更することもできます。次のパラメータを renameByName()
メソッドに渡します。
filename
変更する値新しいファイル名
次の例では、filename
の値が 'my_file'
であるすべてのファイルの名前を変更します。
$bucket->renameByName('my_file', 'new_file_name');
ファイルの削除
GridFSファイルのコレクションドキュメントと関連するチャンクをバケットから削除するには、MongoDB\GridFS\Bucket::delete()
メソッドを使用します。これにより、ファイルが実質的に削除されます。削除するファイルの _id
値をパラメーターとして delete()
メソッドに渡します。
次の例は、_id
フィールドを参照してファイルを削除する方法を示しています。
$bucket->delete(new ObjectId('66e0a5487c880f844c0a32b1'));
または、MongoDB\GridFS\Bucket::deleteByName()
メソッドを使用してGridFSファイルとそのファイルの変更をすべて削除することもできます。次のコードに示すように、削除するファイルの filename
値をパラメーターとして deleteByName()
メソッドに渡します。
$bucket->deleteByName('my_file');
API ドキュメント
MongoDB PHPライブラリを使用して大容量のファイルを保存および検索する方法の詳細については、次のAPIドキュメントを参照してください。