MongoDb GridFS的使用

來源:互聯網
上載者:User

標籤:結構   pos   obj   部署   要求   nuget   list   https   樣本   

MongoDb GridFS 是MongoDB的檔案儲存體方案,主要用於儲存和恢複那些超過16M(BSON檔案限制)的檔案(如:圖片、音頻等),對大檔案有著更好的效能。

要在C#中使用GridFS,首先安裝Nuget包: MongoDB.Driver.GridFS

Bucket

GridFS中的資料也是分集合儲存的,每個集合叫一個bucket,每個bucket裡面可以儲存多個檔案:

在C#中使用bucket和使用集合差不多,建立一個GridFSBucket對象即可。

var bucket = new GridFSBucket(db, new GridFSBucketOptions()
{
    BucketName     = "my_bucket",
    ChunkSizeBytes = 256 * 1024, //塊大小
});

對於bucket,主要的參數就是bucket名稱和塊大小,它也不用手動建立,在使用的時候會自動建立。

 

上傳資料

對於byte[]數組,可以直接使用UploadFromBytes上傳:

var data = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray();
var id = bucket.UploadFromBytes("filename", data);

主要參數是傳入一個檔案名稱(檔案名稱並不要求唯一,同一bucket類可以重複),返回資料id。

也可以帶入metadata資訊。

var options = new GridFSUploadOptions
{
    Metadata = new BsonDocument
    {
        {"resolution", "1080P"},
        {"copyrighted", true}
    },
    DisableMD5 = true,
};
var id   = bucket.UploadFromBytes("filename", data, options);

 

 

上傳Stream

使用UploadFromBytes上傳的時候,需要將上傳的資料全部讀取到記憶體,如果需要上傳的是較大的檔案,這種方式並不合適。此時可以使用UploadFromStream函數上傳。

using (var fs = File.OpenRead(@"r:\123.jpg"))
{
    bucket.UploadFromStream("123.jpg", fs);
}

也可以使用OpenUploadStream的方式開啟為一個Stream,然後通過推的方式完成上傳。

using (var fs = File.OpenRead(@"r:\123.jpg"))
using (var upload = bucket.OpenUploadStream("123.jpg"))
{
    fs.Copy(upload);
    upload.Close();
    Console.WriteLine(upload.Id);
}

注意:這個stream必須手動Close,只是調用Dispose不會寫入到bucket中去。不知道算不算MongoDB API的一個bug。

 

下載:

下載的API和上傳類似,如下是幾個基本樣本:

var id = new ObjectId("5b6ba04c77850928a438b1b2");
var bytes = bucket.DownloadAsBytes(id);

using (var target = File.Create(@"r:\target.jpg"))
{
    bucket.DownloadToStream(id, target);
}

using (var download = bucket.OpenDownloadStream(id))
using (var target = File.Create(@"r:\target.jpg"))
{
    download.CopyTo(target);
}

 

查詢:

GridFS 用兩個集合來儲存一個檔案:fs.files與fs.chunks。對於bucket中的記錄,實際上存成了兩個部分。

  • 檔案的實際內容被存在chunks(位元據)中,拆分成了一堆chunk儲存
  • 相關的描述資訊files集合中,它是一個標準的mongodb的文檔模型,其結構為:
{  "_id" : <ObjectId>,  "length" : <num>,  "chunkSize" : <num>,  "uploadDate" : <timestamp>,  "md5" : <hash>,  "filename" : <string>,  "contentType" : <string>,  "aliases" : <string array>,  "metadata" : <any>,}
gridfs對filename 和uploadDate欄位做了索引的,通過它們查詢能擷取到較好的效能。

參考文檔: https://docs.mongodb.com/manual/core/gridfs/

gridfs的api中封裝了對它的查詢,也是遵循標準的查詢API的

var filter = new {filename = "123.jpg"};
var result = bucket.Find(filter.ToBsonDocument()).ToList();

另外,也可以直接操作fs.files集合。

var files = db.GetCollection<BsonDocument>("my_bucket.files");

 

更新:

GridFS的API支援對文檔重新命名:

bucket.Rename(id, "NewName");

但沒有找打更新MetaData的API,在網上找了一下,有人已經提了這個問題。結論是目前官方沒有封裝,不過可以從fs.files集合中直接更新metadata。樣本如下。

var files = db.GetCollection<BsonDocument>("my_bucket.files");

var filter = new BsonDocument()
{
    ["_id"] = id
};
var update = new BsonDocument()
{
    ["$set"] = new BsonDocument()
    {
        ["metadata"] = metaData
    }
};

files.UpdateOne(filter, update);

 

小結

Gridfs的API封裝還算好用的,就是不過不知道為什麼沒有封裝對描述資訊的更新操作。官方文檔連結如下,要深入學習的可以查看一下。

  • Getting Started
  • Uploading files
  • Downloading files
  • Finding files
  • Deleting and renaming files

本文這裡主要介紹的是GridFS的使用,但需要注意的是,GridFS本身並不是分布式儲存服務,它仍然依賴於MongoDB,並不是解決大規模的分布式儲存的問題的,需要大型存放區和負載平衡等情境建議還是交給FastDFS等專業的服務來。

不過,對於一些效能和容量要求不高的公司專屬應用程式,儲存一些圖片,附件等小規模儲存情境,還是非常合適的。部署和使用都是非常方便快捷的。

另外,網上也有一些深入點介紹GridFS的文檔,也可以看下。

  • http://shift-alt-ctrl.iteye.com/blog/2195646
  • https://juejin.im/entry/57fc27492e958a00559926d5
  • https://www.imooc.com/article/43502

MongoDb GridFS的使用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.