Docs Menu
Docs Home
/ / /
PHP ライブラリ マニュアル
/

大きなファイルの保存

項目一覧

  • Overview
  • GridFS の仕組み
  • GridFS バケットの作成
  • バケットをカスタマイズする
  • ファイルのアップロード
  • アップロード ストリームへの書き込み
  • 既存のストリームをアップロードする
  • ファイル情報の検索
  • ファイルのダウンロード
  • ダウンロード ストリームからの読み取り
  • ファイルの変更をダウンロード
  • 既存のストリームへのダウンロード
  • ファイル名の変更
  • ファイルの削除
  • API ドキュメント

このガイドでは、 GridFSを使用してMongoDBに大容量ファイルを保存、検索する方法を学びます。 GridFSとは、 MongoDB PHPライブラリによって実装された仕様で、ファイルを保存するときにチャンクに分裂し、検索時にファイルを再アセンブルする方法を記述します。ライブラリのGridFSの実装は、ファイルストレージの操作と組織を管理する抽象化です。

ファイルのサイズがBSONドキュメントサイズ制限の16 MB を超える場合は、 GridFSを使用します。 GridFSがユースケースに適しているかどうかの詳細については、 MongoDB Serverマニュアルの GridFSを参照してください。

GridFS により、ファイルはバケット(ファイルのチャンクとそれを説明する情報を含む MongoDB コレクションのグループ)に整理されます。 バケットには、GridFS の仕様に定義されている規則を使用して名前付けされた、以下のコレクションが含まれています。

  • chunks コレクションには、バイナリ ファイルのチャンクがストアされます。

  • files コレクションには、ファイルのメタデータがストアされます。

新しいGridFSバケットを作成すると、別の名前を指定しない限り、ライブラリはデフォルトのバケット名fsを先頭に、前述のコレクションを作成します。ライブラリは各コレクションにインデックスも作成し、ファイルや関連メタデータを効率的に取得できるようにします。ライブラリは、 GridFSバケットが存在しない場合は、最初の書込み操作が実行されたときにのみ GridFS バケット を作成します。ライブラリは、インデックスが存在せず、バケットが空の場合にのみインデックスを作成します。 GridFSインデックスの詳細については、 MongoDB Serverマニュアルの「 GridFSインデックス」を参照してください。

GridFSを使用してファイルを保存する場合、ライブラリはファイルを小さなチャンクに分割し、各ファイルはchunks コレクションに個別のドキュメントとして表されます。また、ファイルID、ファイル名、およびその他のファイルメタデータを含むドキュメントをfiles コレクションに作成します。 MongoDB PHPライブラリにストリームを渡して、新しいストリームを消費または作成し、そのストリームに直接書き込むことで、ファイルをアップロードできます。ストリームの詳細については、「 ストリーム 」を参照してください。 PHPマニュアルを参照してください。

GridFSがバケットにアップロードされるときにファイルを分割する方法を確認するには、次の図を表示します。

GridFS がファイルをバケットにアップロードする方法を示す図

ファイルを検索する際、 GridFSは指定されたバケット内のfilesコレクションからメタデータを取得し、その情報を使用してchunksコレクション内のドキュメントからファイルを再構築します。ファイルの内容を既存のストリームに書き込むか、ファイルをポイントする新しいストリームを作成することで、ファイルを読み取ることができます。

GridFSからファイルを保存または検索するには、データベースでMongoDB\Database::selectGridFSBucket()メソッドを呼び出します。このメソッドは、既存のバケットにアクセスし、バケットが存在しない場合は新しいバケットを作成します。

次の例では、 dbデータベースでselectGridFSBucket()メソッドを呼び出します。

$bucket = $client->db->selectGridFSBucket();

オプション値を指定する配列をselectGridFSBucket()メソッドに渡すことで、 GridFSバケット構成をカスタマイズできます。次の表では、 配列に設定できるオプションの一部を説明しています。

オプション
説明
bucketName
Specifies the bucket name to use as a prefix for the files and chunks collections. The default value is 'fs'.
Type: string
chunkSizeBytes
Specifies the chunk size that GridFS splits files into. The default value is 261120.
Type: integer
readConcern
Specifies the read concern to use for bucket operations. The default value is the database's read concern.
Type: MongoDB\Driver\ReadConcern
readPreference
Specifies the read preference to use for bucket operations. The default value is the database's read preference.
Type: MongoDB\Driver\ReadPreference
writeConcern
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;
}

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);

注意

同じファイル名を持つドキュメントが複数ある場合、 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() メソッドを使用します。名前を変更するファイルは、ファイル名ではなく、ファイルの _id フィールドで指定する必要があります。

次の例では、ドキュメントの_idフィールドを参照してfilenameフィールドを'new_file_name'に更新する方法を示しています。

$bucket->rename(new ObjectId('66e0a5487c880f844c0a32b1'), 'new_file_name');

注意

ファイルの変更

rename()メソッドでサポートされているファイル名の更新は、一度に 1 件のみです。各ファイルリビジョニングの名前を変更したり、同じファイル名を共有するアップロード時間が異なるファイルを変更する場合は、各リビジョニングの_id値を収集します。次に、 rename()メソッドを個別に呼び出して各値を渡します。

バケットからファイルのコレクション ドキュメントと関連するチャンクを削除するには、 MongoDB\GridFS\Bucket::delete()メソッドを使用します。 これにより、ファイルが実質的に削除されます。 削除するファイルは、ファイル名ではなく、 _idフィールドで指定する必要があります。

次の例は、_id フィールドを参照してファイルを削除する方法を示しています。

$bucket->delete(new ObjectId('66e0a5487c880f844c0a32b1'));

注意

ファイルの変更

delete()メソッドでサポートされているファイルの削除は、一度に 1 件のみです。各ファイルのリビジョニング、または同じファイル名を共有するアップロード時間が異なるファイルを削除する場合は、各リビジョニングの_id値を収集します。次に、 delete()メソッドを個別に呼び出して各値を渡します。

MongoDB PHPライブラリを使用して大容量のファイルを保存および検索する方法の詳細については、次のAPIドキュメントを参照してください。

戻る

トランザクションの実行