亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Mongo-go-driver GridFS 元數據

Mongo-go-driver GridFS 元數據

Go
慕絲7291255 2023-06-05 19:32:46
我為我工作的公司編寫了一個聊天應用程序,并且我使用 mgo 驅動程序有一段時間了?,F在我們將mgo重構為官方的mongo驅動。我已經實現了 GridFS 來處理聊天文件,因為它們并不大并且簡化了工作。以前的 mgo 驅動程序在保存文件時有一個數據列表,其中一個字段是 contentType(對吧?)因此,在重構此任務中包含的大部分服務后,我注意到新的官方 mongo 驅動程序不執行此操作??所以我決定嘗試手動添加此字段,但后來我到了我不明白該怎么做的地步?嘗試過,options.GridFSUpload().SetMetadata(metadata)但我不明白它的邏輯,互聯網上關于在 GO 中工作的新 mongo 驅動程序的結果真的很少。任何人都可以給我提示如何將自定義字段添加到文件文檔中?喜歡內容類型??!真的很感激。這是我嘗試做的一個例子// GridFSInsert -func GridFSInsert(fileName string, data []byte, metadata ...bsonx.Elem) (primitive.ObjectID, error) {    checkMongoConnection(false)    var fileID primitive.ObjectID    bucket, bucketErr := gridFs.NewBucket(        Mongo.Client.Database(Mongo.DBName),        options.GridFSBucket().SetName(gridFSColName),    )    if bucketErr != nil {        return fileID, bucketErr    }    uploadStream, uploadStreamErr := bucket.OpenUploadStream(        fileName,        options.GridFSUpload().SetMetadata(metadata),    )    if uploadStreamErr != nil {        return fileID, uploadStreamErr    }    defer uploadStream.Close()    fileSize, writeErr := uploadStream.Write(data)    if writeErr != nil {        return fileID, writeErr    }    fileID = uploadStream.FileID    log.Printf("Write file to DB was succesful, File size: %d", fileSize)    return fileID, nil}對不起,如果我錯過了什么,因為我沒有像我想的那樣有 GO 的經驗。謝謝你的幫助
查看完整描述

2 回答

?
qq_花開花謝_0

TA貢獻1835條經驗 獲得超7個贊

您沒有試圖理解的邏輯。在新的官方 mongo 驅動程序中找不到太多關于 contentType 的原因是因為在編寫驅動程序之前很久,contentType 在 gridfs 規范中就已被棄用。

我必須承認gridfs 文檔沒有提到它。事實上,官方的 mongofiles cli 仍然使用傳統格式。

規范直截了當:

注意:一些舊版本的 GridFS 實現允許應用程序在根級別向文件集合文檔添加任意字段。GridFS 的新實現將不允許這樣做,但必須準備好處理可能具有附加字段的現有文件集合文檔。

如果你喜歡更詳細的官方推理:

為什么不推薦使用 contentType?

文件集合文檔中的大多數字段都由驅動程序直接使用,但元數據、內容類型和別名除外。所有純粹供應用程序使用的信息都應嵌入“元數據”文檔中。鼓勵希望存儲 contentType 以在其應用程序中使用的 GridFS 用戶將“contentType”字段添加到“元數據”文檔,而不是使用已棄用的頂級“contentType”字段。

這有點道理。contentType驅動程序從字面上遵循規范的措辭——除了在 中,無法在任何地方創建屬性metadata,但 Bucket.Find 仍將返回contentType由“舊版本”創建的文件。

從遺留 gridfs 到新格式的一次性轉換可以很簡單:

db.getCollection("fs.files").aggregate([

? ? {$addFields: {?

? ? ? ? "length" : {$toLong: "$length"},

? ? ? ? "metadata.contentType": { $ifNull: [ "$contentType", "$metadata.contentType" ] }?

? ? }},

? ? { $out : "fs.files" }

])

假設您的存儲桶默認為“fs”并且您不會以舊格式上傳文件。如果您有足夠的可用空間,那么創建新的臨時集合、驗證它然后重命名并不是一個糟糕的主意out。


如果出于任何原因必須支持舊版格式,您仍然可以直接訪問 gridfs 集合:


// in your code snippet after

fileID = uploadStream.FileID


// update the document that represent uploaded file

files := db.Collection("fs.files")

updateResult, err := files.UpdateOne(

? ? context.Background(),

? ? bson.D{{"_id", fileID}},

? ? bson.D{{"$set", bson.D{{"contentType", contentType}}}},

)

其中“fs”是您的存儲桶名稱,contentType是您要設置為 contentType 的字符串值。


請記住,“一些舊版本”使用 int32 作為文件長度。新驅動程序期望它是 int64。對于單獨使用 *.fiiles 集合的類似查找的操作應該沒問題,但可能會導致使用新的官方驅動程序下載此類文件時出現問題。


查看完整回答
反對 回復 2023-06-05
?
茅侃侃

TA貢獻1842條經驗 獲得超22個贊

這是一個例子SetMetadata()。


opts := options.GridFSUpload()

opts.SetMetadata(bsonx.Doc{{Key: "content-type", Value: bsonx.String("application/json")}})

if ustream, err = bucket.OpenUploadStream("test.txt", opts); err != nil {

? ? t.Fatal(err)

}

查看完整回答
反對 回復 2023-06-05
  • 2 回答
  • 0 關注
  • 197 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號