2 回答
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 集合的类似查找的操作应该没问题,但可能会导致使用新的官方驱动程序下载此类文件时出现问题。
TA贡献1842条经验 获得超21个赞
这是一个例子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)
}
- 2 回答
- 0 关注
- 139 浏览
添加回答
举报