Overview
このガイドでは、 GridFS を使用してMongoDBに大容量ファイルを保存、検索する方法を学びます。GridFS は、ファイルを保存するときにチャンクに分裂し、検索時にファイルを再アセンブルする方法を記述するCドライバーによって実装された仕様です。 ドライバーのGridFSの実装は、ファイルストレージの操作と組織を管理する抽象化です。
Use GridFS if the size of your files exceeds the BSON document size limit of 16MB. For more detailed information on whether GridFS is suitable for your use case, see GridFS in the MongoDB Server manual.
GridFS の仕組み
GridFS により、ファイルはバケット(ファイルのチャンクとそれを説明する情報を含む MongoDB コレクションのグループ)に整理されます。 バケットには、GridFS の仕様に定義されている規則を使用して名前付けされた、以下のコレクションが含まれています。
chunksコレクションにはバイナリ ファイルのチャンクがストアされます。filesコレクションには、ファイルのメタデータがストアされます。
ドライバーは、 最初の書込み (write)操作を実行するときに、 GridFSバケットが存在しない場合はそれを作成します。 バケットには、別の名前を指定しない限り、デフォルトのバケット名 fs がプレフィックスが付いた前述のコレクションが含まれます。 ドライバーはファイルと関連するメタデータを効率的に取得するために、コレクションが存在しない場合とバケットが空の場合に、各コレクションにインデックスも作成します。
For more information about GridFS indexes, see GridFS Indexes in the MongoDB Server manual.
GridFS を使用してファイルを保存する場合、ドライバーはファイルを小さなチャンクに分割し、各ファイルは chunksコレクションに個別のドキュメントとして表されます。 また、ファイルID、ファイル名、およびその他のファイルメタデータを含むドキュメントを filesコレクションに作成します。 Cドライバーにストリームを渡して、新しいストリームを消費するか作成して、そのストリームに直接書き込むことで、ファイルをアップロードできます。
次の図は、 GridFSがバケットにアップロードされるときにファイルを分割する方法を示しています。

GridFSからファイルを検索すると、指定されたバケット内の filesコレクションからメタデータが取得され、その情報を使用して chunksコレクション内のドキュメントからファイルを再構築します。 ファイルの内容を既存のストリームに書き込むか、ファイルをポイントする新しいストリームを作成することで、ファイルを読み取ることができます。
GridFS バケットの作成
GridFS を使用するには、まず mongoc_gridfs_bucket_new() 関数を呼び出します。 この関数は、新しい mongoc_gridfs_bucket_t 構造を作成するか、既存の mongoc_gridfs_bucket_t にアクセスし、次のパラメータを受け入れます。
データベース :バケットを作成するデータベースを指定します
オプションドキュメント:バケットをカスタマイズするオプションを指定します。または
NULL読み込み設定(read preference) : 読み取り操作に使用する読み込み設定 (read preference)を指定します。または、データベースの読み込み設定
NULL(read preference)を継承するには、 がエラー ロケーション : エラー値のロケーションを指定します。または
NULL
次の例では、 mongoc_gridfs_bucket_new() 関数を呼び出し、dbデータベースをパラメーターとして渡します。
mongoc_database_t *db = mongoc_client_get_database(client, "db"); bson_error_t error; mongoc_gridfs_bucket_t *bucket = mongoc_gridfs_bucket_new(db, NULL, NULL, &error); if (!bucket) { fprintf(stderr, "Failed to create bucket: %s\n", error.message); }
バケットをカスタマイズする
GridFSバケット構成をカスタマイズするには、オプション値を指定するBSONドキュメントをmongoc_gridfs_bucket_new() 関数に渡します。 次の表では、ドキュメントで設定できるオプションについて説明します。
オプション | 説明 |
|---|---|
| ファイルとチャンク コレクションのプレフィックスとして使用するバケット名を指定します。デフォルト値は |
| GridFS がファイルを分割するチャンクサイズを指定します。デフォルト値は 255 kB です。 |
| バケット操作に使用する読み取り保証 (read concern)を指定します。デフォルト値はデータベースの読み取り保証 (read concern)です。 |
| バケット操作に使用する書込み保証 (write concern)を指定します。デフォルト値はデータベースの書込み保証 (write concern)です。 |
次の例では、 bucketName オプションを設定するオプションドキュメントをmongoc_gridfs_bucket_new() に渡して、"myCustomBucket" という名前のバケットを作成します。
mongoc_database_t *db = mongoc_client_get_database(client, "db"); bson_t opts = BSON_INITIALIZER; BSON_APPEND_UTF8(&opts, "bucketName", "myCustomBucket"); bson_error_t error; if (!mongoc_gridfs_bucket_new(db, &opts, NULL, &error)) { fprintf(stderr, "Failed to create bucket: %s\n", error.message); }
ファイルのアップロード
次の機能を使用して、 GridFSバケットにファイルをアップロードできます。
mongoc_gridfs_bucket_open_upload_stream(): 新しいアップロードストリームを開き、ファイルの内容を書き込むことができますmongoc_gridfs_bucket_upload_from_stream(): 既存のストリームの内容をGridFSファイルにアップロードします
アップロード ストリームへの書き込み
特定のファイル名でアップロード ストリームを作成するには、mongoc_gridfs_bucket_open_upload_stream() 関数を使用します。 mongoc_gridfs_bucket_open_upload_stream() 関数を使用すると、 オプションドキュメントで構成情報を指定できます。これはパラメーターとして渡します。
この例では、アップロードストリームを使用して次のアクションを実行しています。
次の名称の新しいGridFSファイルの書込み可能なストリームを開きます:
"my_file"mongoc_stream_write()関数を呼び出して、ストリームがポイントする"my_file"にデータを書込みます。mongoc_stream_close()関数とmongoc_stream_destroy()関数を呼び出して、"my_file"を指しているストリームを閉じて破棄します
bson_error_t error; mongoc_stream_t *upload_stream = mongoc_gridfs_bucket_open_upload_stream(bucket, "my_file", NULL, NULL, &error); if (upload_stream == NULL) { fprintf(stderr, "Failed to create upload stream: %s\n", error.message); } else { const char *data = "Data to store"; mongoc_stream_write(upload_stream, data, strlen(data), -1); } mongoc_stream_close(upload_stream); mongoc_stream_destroy(upload_stream);
既存のストリームをアップロードする
ストリームの内容を新しいGridFSファイルにアップロードするには、mongoc_gridfs_bucket_upload_from_stream() 関数を使用します。 mongoc_gridfs_bucket_upload_from_stream() 関数を使用すると、 オプションドキュメントで構成情報を指定できます。これはパラメーターとして渡します。
この例では、次のアクションを実行します。
mongoc_stream_file_new_for_path()関数を呼び出して、/path/to/input_fileにあるファイルを読み取り専用(O_RDONLY)モードのストリームとして開きますmongoc_gridfs_bucket_upload_from_stream()関数を呼び出して、ストリームの内容を"new_file"という名前のGridFSファイルにアップロードしますストリームを閉じて破棄するには、
mongoc_stream_close()関数とmongoc_stream_destroy()関数を呼び出します
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path("/path/to/input_file", O_RDONLY, 0); bson_error_t error; if (!mongoc_gridfs_bucket_upload_from_stream(bucket, "new_file", file_stream, NULL, NULL, &error)) { fprintf(stderr, "Failed to upload file: %s\n", error.message); } mongoc_stream_close(file_stream); mongoc_stream_destroy(file_stream);
ファイル情報の検索
このセクションでは、 GridFSバケットの filesコレクションに保存されているファイルメタデータを検索する方法を学びます。 ファイルのメタデータには、参照先のファイルに関する次のような情報が含まれます。
ファイルの
_idファイルの名前
ファイルの長さ/サイズ
アップロード日時
その他の情報をストアできる
metadataドキュメント
GridFSバケットからファイルを検索するには、mongoc_gridfs_bucket_find() 関数を呼び出し、バケットをパラメーターとして渡します。 この関数は、結果にアクセスできるカーソルを返します。
Tip
Cドライバーのカーソルの詳細については、「 カーソルからデータにアクセスする 」ガイドを参照してください。
例
次のコード例は、 GridFSバケット内のファイルからファイルメタデータを検索して印刷する方法を示しています。 whileループを使用して返されたカーソルを反復処理し、 ファイルのアップロード例 にアップロードされたファイルの内容を表示します。
mongoc_cursor_t *cursor = mongoc_gridfs_bucket_find(bucket, bson_new(), NULL); const bson_t *file_doc; while (mongoc_cursor_next(cursor, &file_doc)) { char *json = bson_as_json(file_doc, NULL); printf("%s\n", json); bson_free(json); } mongoc_cursor_destroy(cursor);
mongoc_gridfs_bucket_find() 関数はさまざまなクエリ仕様を受け入れます。オプション パラメーターを使用して、ソート順序、返されるドキュメントの最大数、返される前にスキップするドキュメント数を指定できます。使用可能なオプションのリストを表示するには、mongoc_collection_find_with_opts() APIドキュメント を参照してください。
ファイルのダウンロード
次の機能を使用して、 GridFSバケットからファイルをダウンロードできます。
mongoc_gridfs_bucket_open_download_stream(): 新しいダウンロードストリームを開き、ファイルの内容を読み取れるmongoc_gridfs_bucket_download_to_stream():ファイル全体を既存のダウンロード ストリームに書き込みます
ダウンロード ストリームからの読み取り
MongoDBデータベースからファイルをダウンロードするには、mongoc_gridfs_bucket_open_download_stream() 関数を使用してダウンロード ストリームを作成します。
この例では、ダウンロード ストリームを使用して次のアクションを実行しています。
mongoc_gridfs_bucket_open_download_stream()関数を呼び出して、指定された_id値を持つGridFSファイルを選択し、それを読み取り可能なストリームとして開きますファイルの内容を読み取るには、
mongoc_stream_read()関数を呼び出しますmongoc_stream_close()関数とmongoc_stream_destroy()関数を呼び出して、ファイルを指しているダウンロード ストリームを閉じて破棄します
char buf[512]; bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string(&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); bson_error_t error; mongoc_stream_t *download_stream = mongoc_gridfs_bucket_open_download_stream(bucket, &file_id, &error); if (!download_stream) { fprintf(stderr, "Failed to create download stream: %s\n", error.message); } mongoc_stream_read(download_stream, buf, 1, 1, 0); mongoc_stream_close(download_stream); mongoc_stream_destroy(download_stream);
注意
同じファイル名を持つドキュメントが複数ある場合、 GridFSは指定された名前( uploadDateフィールドによって決定)を持つ最新のファイルをストリーミングします。
既存のストリームへのダウンロード
mongoc_gridfs_bucket_download_to_stream() 関数を呼び出すと、 GridFSファイルの内容を既存のストリームにダウンロードできます。
この例では、次のアクションを実行します。
mongoc_stream_file_new_for_path()関数を呼び出して、/path/to/output_fileにあるファイルを読み取りおよび書込み(O_RDWR)モードのストリームとして開きます指定された
_id値を持つGridFSファイルをストリームにダウンロードファイルストリームを閉じて破棄するには、
mongoc_stream_close()関数とmongoc_stream_destroy()関数を呼び出します
mongoc_stream_t *file_stream = mongoc_stream_file_new_for_path("/path/to/output_file", O_RDWR, 0); bson_error_t error; if (!file_stream) { fprintf(stderr, "Error opening file stream: %s\n", error.message); } bson_value_t file_id; file_id.value_type = BSON_TYPE_OID; bson_oid_init_from_string(&file_id.value.v_oid, "66fb1b8ea0f84a74ee099e71"); if (!mongoc_gridfs_bucket_download_to_stream(bucket, &file_id, file_stream, &error)) { fprintf(stderr, "Failed to download file: %s\n", error.message); } mongoc_stream_close(file_stream); mongoc_stream_destroy(file_stream);
ファイルの削除
mongoc_gridfs_bucket_delete_by_id() 関数を使用して、ファイルのコレクションドキュメントと関連するチャンクをバケットから削除します。 これにより、ファイルが実質的に削除されます。
次の例は、_id フィールドを参照してファイルを削除する方法を示しています。
bson_error_t error; bson_oid_t oid; bson_oid_init_from_string(&oid, "66fb1b365fd1cc348b031b01"); if (!mongoc_gridfs_bucket_delete_by_id(bucket, &oid, &error)) { fprintf(stderr, "Failed to delete file: %s\n", error.message); }
注意
ファイルの変更
mongoc_gridfs_bucket_delete_by_id() 関数は一度に 1 つのファイルの削除のみをサポートします。 各ファイルのリビジョニング、または同じファイル名を共有するアップロード時間が異なるファイルを削除する場合は、各リビジョニングの _id 値を収集します。 次に、mongoc_gridfs_bucket_delete_by_id() 関数を個別に呼び出して、各 _id 値を渡します。
API ドキュメント
Cドライバーを使用して大容量のファイルを保存および検索する方法の詳細については、次のAPIドキュメントを参照してください。