多くのアプリケーションはファイル管理を含み、データ処理を強化するための重要な機能としてファイルストレージを備えています。多くの場合、ファイルストレージにはAmazon WebサービスなどのサードパーティのCDN(コンテンツ配信ネットワーク)が必要ですが、これにより管理プロセスが少し面倒になります。取得中に障害が発生する可能性があるため、複数のクラウドストレージではなく、単一のクラウドストレージからすべてのリソースにアクセスする方が簡単です。
単一のAPI呼び出しを介してデータベースにファイルを直接保存することは、MongoDBにGridFSが導入されるまで簡単に行うことはできませんでした。
MongoDBGridFSとは
GridFsは、ビデオ、オーディオ、画像などの大きなファイルの保存と復元に使用されるMongoDBの抽象化レイヤーです。このファイルシステムは、MongoDBデータコレクション内に16MBよりもさらに重要なファイルを保存します。ファイルは、最初にデータの小さなチャンクに分割して保存されます。各データのサイズは255KBです。
GridFSは、2つの収集システムを使用してファイルを保存します。
- チャンク :これは、ドキュメントパーツを格納するコレクションです。チャンクはそれぞれ255KBのサイズに制限されており、クエリを実行すると、GridFSドライバーはストレージの一意の_idに従ってすべてのチャンクを再構築します。たとえば、ファイル全体ではなく、ビデオファイルの一部を取得したい場合があります。これは、必要な正しい範囲を照会するだけで可能です。
- ファイル :これにより、ファイルの結果として生じる追加のメタデータが保存されます。
コレクションは共通のバケットに配置され、それぞれにバケット名のプレフィックスが付けられます。デフォルトではfsであるため、次のようになります。
- fs.chunks
- fs.files
別のバケット名を選択できますが、完全なコレクション名には、255バイトの名前空間制限が適用されます。
チャンクコレクションドキュメントの形式は次のとおりです:
{
"_id" : <ObjectId>,
"files_id" : <ObjectId>,
"n" : <num>,
"data" : <binary>
}
- _id:はチャンクの一意の識別子です
- files_id:ファイルコレクションに保存されている親ドキュメントの_idです
- n:は0から始まるチャンクのシーケンス番号です。
- data:はBSONバイナリタイプとしてのチャンクのペイロードです。
files_idフィールドとnフィールドを使用する複合インデックスは、チャンクを効率的に取得できるようにするために使用されます。例:
db.fs.chunks.find( { files_id: fileId } ).sort( { n: 1 } )
このインデックスが存在しない場合に作成するには、mongoシェルで次のコマンドを実行できます。
db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
{
"_id" : <ObjectId>,
"length" : <num>,
"chunkSize" : <num>,
"uploadDate" : <timestamp>,
"filename" : <string>,
"metadata" : <any>,
}
- _id:元のドキュメント用に選択したデータ型のドキュメントの一意の識別子であり、MongoDBではデフォルトでBSONObjectIdです。
- 長さ:ドキュメントのサイズ(バイト単位)
- chunkSize:255キロバイトに制限されている各チャンクのサイズ
- uploadDate:ドキュメントが最初に保存された日付を格納するDateタイプのフィールド。
- ファイル名:これは、ファイルの人間が読める形式のIDであるオプションのフィールドです。
- メタデータ:これは、保存したい追加情報を保持するオプションのフィールドです。
fsファイルの例を以下に示します。
{
"filename": "file.html",
"chunkSize": NumberInt(23980),
"uploadDate": ISODate("2020-08-11T10:02:15.237Z"),
"length": NumberInt(312)
}
チャンクコレクションと同様に、filenameフィールドとuploadDateフィールドを使用する複合インデックスがファイルコレクションで使用され、ファイルを効率的に取得できるようになります。例:
db.fs.files.find( { filename: fileName } ).sort( { uploadDate: 1 } )
このインデックスが存在しない場合に作成するには、mongoシェルで次のコマンドを実行できます。
db.fs.file.createIndex( { filename: 1, uploadDate: 1 }, { unique: true } );
MongoDBGridFSストレージシステムを使用する場合
MongoDB GridFSは一般的に使用されていませんが、このGridFSストレージシステムの使用が必要になる可能性のある条件は次のとおりです。
- 現在のファイルシステムで、特定のディレクトリに保存できるファイルの数に制限がある場合。
- 保存されている情報の一部にアクセスする場合、GridFSを使用すると、ドキュメント全体にアクセスせずにファイルの一部を呼び出すことができます。
- 地理的に分散したレプリカセットを介してファイルとそのメタデータを配布する場合、GridFSを使用すると、メタデータを同期して、複数のターゲットシステム間でデータを自動的に展開できます。
ただし、GridFSに保存されているファイル全体のコンテンツを更新する必要がある場合は、GridFSストレージシステムの使用は適切ではありません。
GridFを使用してMongoDBにmp3ファイルを保存する場合、従うべき正しい手順は次のとおりです。
- ターミナルを開きます(コマンドプロンプト)
- mongofiles.exeに移動します(これはbinフォルダーにあります)
- コマンド
>mongofiles.exe -d gridfs put song.mp3
コマンドの後、使用されるデータベースの名前はgridfsです。偶然に名前が欠落している場合、MongoDBはファイルをデータベースに保存するドキュメントを自動的に作成します。
GridFSに保存されているファイルを表示するには、mongoシェルで以下のクエリコマンドを使用します;
>db.fs.files.find()
このコマンドは、以下に示す形式のドキュメントを返します。
{
_id: ObjectId('526a922bf8b4aa4d33fdf84d'),
filename: "song.mp3",
chunkSize: 233390,
uploadDate: new Date(1397391643474), md5: "e4f53379c909f7bed2e9d631e15c1c41",
length: 10302960
}
ファイルには、ファイル名、長さ、アップロード日、チャンクサイズ、object_idの詳細が含まれています。 fs.chunksコレクションのチャンクは、以下に示すように、最初のクエリで返されたIDを使用して表示できます。
>db.fs.chunks.find({files_id:ObjectId('526a922bf8b4aa4d33fdf84d')})
GridFSシャーディング
シャーディングも、GridFSに適用できるもう1つの機能です。チャンクコレクションをシャードするには、シャードキーとして{files_id:1、n:1}または{files_id:1}の複合インデックスを使用できます。
Harshed Shardingは、MongoDBドライバーがfilemd5を実行しない場合にのみ可能です。
ファイルコレクションはメタデータのみを含み、非常に小さいため、シャーディングされないことがよくあります。使用可能なキーは、シャーディングされたクラスターで均等に分散することもできません。ただし、ファイルコレクションをシャーディングする必要がある場合は、_idフィールドをいくつかのアプリケーションフィールドと組み合わせて使用できます。
GridFSの制限
GridFSファイルシステムには次の制限があります。
- アトミックアップデート: GridFSにはアトミックアップデートはありません。これにより、必要なバージョンのファイルを選択し、複数のバージョンのファイルを実行し続けることで、手動で更新することが容易になります。
- パフォーマンス :ファイルシステムとウェブサーバーではシステムが遅くなる傾向があります。
- ワーキングセット: 新しいワーキングセットで作業するときに別のサーバーを使用します。これは、実行中のワーキングセットの邪魔にならないようにするために行われます。
GridFSは、MongoDBに大きなファイルを保存しようとする開発者にとっては特効薬のようなものです。 GridFSストレージシステムは、開発者に大きなファイルを保存し、必要なファイルの一部を取得する機会を提供します。したがって、GridFSは、さまざまなアプリケーションで使用できる優れたMongoDB機能です。