猿问

Mongo-go-driver GridFS 元数据

我为我工作的公司编写了一个聊天应用程序,并且我使用 mgo 驱动程序有一段时间了。现在我们将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 的经验。


谢谢你的帮助


慕丝7291255
浏览 140回答 2
2回答

qq_花开花谢_0

您没有试图理解的逻辑。在新的官方 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 afterfileID = uploadStream.FileID// update the document that represent uploaded filefiles := 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 集合的类似查找的操作应该没问题,但可能会导致使用新的官方驱动程序下载此类文件时出现问题。

茅侃侃

这是一个例子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)}
随时随地看视频慕课网APP

相关分类

Go
我要回答