Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/ / /
C ドライバー
/

大きなファイルの保存

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

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

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

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

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

ドライバーは、 最初の書込み (write)操作を実行するときに、 GridFSバケットが存在しない場合はそれを作成します。 バケットには、別の名前を指定しない限り、デフォルトのバケット名 fs がプレフィックスが付いた前述のコレクションが含まれます。 ドライバーはファイルと関連するメタデータを効率的に取得するために、コレクションが存在しない場合とバケットが空の場合に、各コレクションにインデックスも作成します。

GridFSインデックスの詳細については、 MongoDB Serverマニュアルの「 GridFSインデックス 」を参照してください。

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

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

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

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

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;
if (!mongoc_gridfs_bucket_new (db, NULL, NULL, &error)) {
fprintf (stderr, "Failed to create bucket: %s\n", error.message);
}

GridFSバケット構成をカスタマイズするには、オプション値を指定するBSONドキュメントをmongoc_gridfs_bucket_new() 関数に渡します。 次の表では、ドキュメントで設定できるオプションについて説明します。

オプション
説明

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 255 kB.
Type: int32

readConcern

Specifies the read concern to use for bucket operations. The default value is the database's read concern.
Type: mongoc_read_concern_t

writeConcern

Specifies the write concern to use for bucket operations. The default value is the database's write concern.
Type: mongoc_write_concern_t

次の例では、 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);
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" :
{ "$date" : ... }, "filename" : "my_file", "metadata" : { } }
{ "_id" : { "$oid" : "..." }, "length" : 13, "chunkSize" : 261120, "uploadDate" :
{ "$date" : ... }, "filename" : "new_file", "metadata" : { } }

The mongoc_gridfs_bucket_find() function accepts various query specifications. You can use its options parameter to specify the sort order, maximum number of documents to return, and the number of documents to skip before returning. To view a list of available options, see the mongoc_collection_find_with_opts() API documentation.

次の機能を使用して、 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 値を渡します。

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

戻る

トランザクション