gpt4 book ai didi

mongodb - Mongo-go-driver GridFS 元数据

转载 作者:IT王子 更新时间:2023-10-29 02:35:39 27 4
gpt4 key购买 nike

我为我工作的公司编写了一个聊天应用程序,并且我使用 mgo 驱动程序有一段时间了。现在我们将mgo重构为官方的mongo驱动。我已经实现了 GridFS 来处理聊天文件,因为它们并不大并且简化了工作。以前的 mgo 驱动程序在保存文件时有一个数据列表,其中一个字段是 contentType(对吧?)

因此,在重构此任务中包含的大部分服务后,我注意到新的官方 mongo 驱动程序不会执行此操作??

所以我决定尝试手动添加此字段,但后来我不知道该怎么做?

尝试使用 options.GridFSUpload().SetMetadata(metadata) 但我不明白它的逻辑,互联网上关于在 GO 中工作的新 mongo 驱动程序的结果真的很少。

任何人都可以给我提示如何将自定义字段添加到文件文档中?喜欢 contentType!!

非常感谢。

这是我尝试做的一个例子

// 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 的体验并不如我所愿。

感谢您的帮助

最佳答案

没有您试图理解的逻辑。在新的官方 mongo 驱动程序中找不到太多关于 contentType 的原因是因为 contentType has been deprecated in gridfs spec早在编写驱动程序之前。

我必须承认gridfs documentation没有提到它。事实上,官方的 mongofiles cli 仍然使用旧格式。

规范直接说明了这一点:

Note: some older versions of GridFS implementations allowed applications to add arbitrary fields to the files collection document at the root level. New implementations of GridFS will not allow this, but must be prepared to handle existing files collection documents that might have additional fields.

如果你喜欢更详细的official reasoning :

Why is contentType deprecated?

Most fields in the files collection document are directly used by the driver, with the exception of: metadata, contentType and aliases. All information that is purely for use of the application should be embedded in the 'metadata' document. Users of GridFS who would like to store a contentType for use in their applications are encouraged to add a 'contentType' field to the ‘metadata’ document instead of using the deprecated top-level ‘contentType’ field.

这有点道理。驱动程序从字面上遵循规范的措辞 - 除了在 metadata 中之外,无法在任何地方创建 contentType 属性,但 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 集合的类似查找的操作应该没问题,但可能会导致使用新的官方驱动程序下载此类文件时出现问题。

关于mongodb - Mongo-go-driver GridFS 元数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54712830/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com