技術乾貨| 如何在MongoDB中輕鬆使用GridFS?

GridFS是用於存儲和檢索超過16 MB大小限制的BSON文檔文件的規範。

注意

GridFS 不支持多文檔事務

相較於將一個文件存儲在單條文檔中,GridFS將文件分爲多個部分或塊[1],並將每個塊存儲爲單獨的文檔。默認情況下,GridFS使用的塊默認大小爲255kB;也就是說,除最後一個塊,GridFS會將文件劃分爲255 kB的塊。最後一個塊只有必要的大小。同樣,最後的那個塊也不會大於默認的塊大小,僅使用所需的空間以及一些其他元數據。

GridFS使用兩個集合來存儲文件。一個集合存儲文件塊,另一個集合存儲文件元數據。 GridFS集合一節詳細介紹了每個集合。

當你從GridFS查詢文件時,驅動程序將根據需要重新組裝該文件所有的塊。你可以對GridFS存儲的文件進行範圍查詢。你還可以從文件的任意部分訪問其信息,例如“跳到”視頻或音頻文件的中間。

GridFS不僅可用於存儲超過16 MB的文件,而且還可用於存儲您要訪問的任何文件而不必將整個文件加載到內存中。另請參閱何時使用GridFS。

什麼時候使用GridFS

在MongoDB中,使用GridFS存儲大於16 MB的文件。

在某些情況下,在MongoDB數據庫中存儲大型文件可能比在系統級文件系統上存儲效率更高。

如果文件系統限制了目錄中文件的數量,則可以使用GridFS來存儲所需數量的文件。

當你要訪問大文件部分的信息而不必將整個文件加載到內存中時,可以使用GridFS來調用文件的某些部分,而無需將整個文件讀入內存。

當你希望保持文件和元數據在多個系統和設施之間自動同步和部署時,可以使用GridFS。使用地理分佈的複製集時,MongoDB可以自動將文件及其元數據分發到多個mongod實例和設施。

如果您需要對整個文件的內容進行原子更新,請不要使用GridFS。或者,您可以存儲每個文件的多個版本,並在元數據中指定文件的當前版本。上傳文件的新版本後,您可以原子更新元數據中指示爲“最新”狀態的字段,然後在需要時刪除以前的版本。

此外,如果文件均小於16 MB BSON文檔大小限制,請考慮將每個文件存儲在單個文檔中,而不是使用GridFS。您可以使用BinData數據類型存儲二進制數據。有關使用BinData的詳細信息,請參見驅動程序文檔。

使用GridFS

要使用GridFS存儲和檢索文件,請使用以下任一方法:

MongoDB驅動程序。請參閱驅動程序文檔,以獲取有關將GridFS與驅動程序一起使用的信息。

mongofiles命令行工具。有關文檔,請參見mongofiles參考。

GridFS Collections

GridFS將文件存儲在兩個集合中:

塊存儲二進制塊。有關詳細信息,請參見chunks集合。

文件存儲文件的元數據。有關詳細信息,請參見文件集合。

GridFS通過使用存儲桶名稱爲每個集合添加前綴,將集合放置在一個公共存儲桶中。默認情況下,GridFS使用兩個集合以及一個名爲fs的存儲桶:

fs.files

fs.chunks

您可以選擇其他存儲桶名稱,也可以在一個數據庫中創建多個存儲桶。完整集合名稱(包括存儲桶名稱)受命名空間長度限制。

塊集合

塊[1]集合中的每個文檔都代表了GridFS中表示的文件的不同的塊。此集合中的文檔具有以下格式:

{
  "_id" : <ObjectId>,
  "files_id" : <ObjectId>,
  "n" : <num>,
  "data" : <binary>
}

chunks集合中的文檔包含以下字段:

chunks._id

塊的唯一ObjectId。

chunks.files_id

在files集合中指定的“父”文檔的_id。

chunks.n

塊的序列號。GridFS從0開始對所有塊進行編號。

chunks.data

塊BSON二進制類型的荷載。

文件集合

文件集合中的每個文檔代表GridFS中的一個文件。

{
  "_id" : <ObjectId>,
  "length" : <num>,
  "chunkSize" : <num>,
  "uploadDate" : <timestamp>,
  "md5" : <hash>,
  "filename" : <string>,
  "contentType" : <string>,
  "aliases" : <string array>,
  "metadata" : <any>,
}

files集合中的文檔包含以下一些或全部字段:

files._id

該文檔的唯一標識符。 _id是您爲原始文檔選擇的數據類型。MongoDB文檔的默認類型是BSON ObjectId。

files.length

文檔的大小(以字節爲單位)。

files.chunkSize

每個塊的大小(以字節爲單位)。GridFS將文檔分爲大小爲chunkSize的塊,最後一個除外,後者僅根據需要而變大。默認大小爲255 KB。

files.uploadDate

GridFS首次存儲這個文檔的日期。此值爲有日期類型。

files.md5

過期

FIPS 140-2禁止使用MD5算法。MongoDB驅動程序已棄用MD5支持,並將在未來版本中刪除MD5的生成。需要文件摘要的應用程序應在GridFS外部實現它,並將其存儲在files.metadata中。

filemd5命令返回的完整文件的MD5哈希。此值爲字符串類型。

files.filename

可選的。GridFS文件的可讀名稱。

files.contentType

過期

可選的。GridFS文件的有效MIME類型。僅應用程序用。

使用files.metadata來存儲與GridFS文件的MIME類型有關的信息。

files.aliases

過期

可選的。別名字符串數組。僅用於應用程序

使用files.metadata來存儲與GridFS文件的MIME類型有關的信息。

files.metadata

可選的。元數據字段可以是任何數據類型,並且可以保存您要存儲的任何其他信息。如果希望將其他任意字段添加到文件集合中的文檔,請將其添加到元數據字段中的對象。

GridFS索引

GridFS使用每個塊和文件集合上的索引來提高效率。爲了方便起見,符合GridFS規範的驅動程序會自動創建這些索引。您還可以根據需要創建任何其他索引,以滿足您的應用程序需求。

chunks索引

GridFS使用files_id和n字段在chunks集合上使用唯一的複合索引。可以有效地檢索塊,如以下示例所示:

db.fs.chunks.find( { files_id: myFileID } ).sort( { n: 1 } )
符合GridFS規範的驅動程序將在讀取和寫入操作之前自動確保此索引存在。有關GridFS應用程序的特定行爲,請參閱相關的驅動程序文檔。

如果該索引不存在,則可以執行以下操作以使用mongo shell創建它:

db.fs.chunks.createIndex( { files_id: 1, n: 1 }, { unique: true } );
files索引
GridFS在files集合上的filename和uploadDate字段上使用索引。該索引允許高效地檢索文件,如本示例所示:

db.fs.files.find( { filename: myFileName } ).sort( { uploadDate: 1 } )
符合GridFS規範的驅動程序將在讀取和寫入操作之前自動確保此索引存在。有關GridFS應用程序的特定行爲,請參閱相關的驅動程序文檔。

如果該索引不存在,則可以執行以下操作以使用mongo shell創建它:

db.fs.files.createIndex( { filename: 1, uploadDate: 1 } );
[1] (1, 2) 在GridFS上下文中使用術語塊與在分片上下文中使用術語塊無關。

分片GridFS

GridFS考慮兩個集合-files和chunks。

chunks集合

要分片chunks集合,請使用{ files_id : 1, n : 1 } 或{ files_id : 1 } 作爲分片鍵索引。files_id是一個ObjectId,並且單調更改。

對於不運行filemd5來驗證成功上傳的MongoDB驅動程序(例如,支持MongoDB 4.0或更高版本的MongoDB驅動程序),可以將哈希分片用於chunks集合。

如果MongoDB驅動程序運行filemd5,則不能使用Hashed Sharding。有關詳細信息,請參閱SERVER-9888。

files集合
files集合很小,僅包含元數據。GridFS所需的所有密鑰都不適合在分片環境中進行平均分配。保留未分片的files允許所有文件元數據文檔保留在主分片上。

如果必須分片files集合,請使用_id字段,可能與應用程序字段結合使用。

原文鏈接:

https://github.com/mongodb-china/MongoDB-CN-Manual/blob/master/cun-chu/gridfs.md

關於作者:張琦

Java 開發工程師,陝西西安。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章