Mongo-go-driver метаданные GridFS - PullRequest
0 голосов
/ 15 февраля 2019

Я написал приложение для чата для компании, в которой я работаю, и некоторое время работал с драйвером mgo.Теперь мы проводим рефакторинг MGO к официальному драйверу Монго.Я реализовал GridFS для работы с файлами чата, так как они невелики, и это упрощает работу.Предыдущий драйвер mgo при сохранении файлов имел список данных, одним из полей которого был contentType (отлично?)

Так что после рефакторинга большинства служб, которые были включены в эту задачу, я заметил, что новый официальныйДрайвер Монго этого не делает ??

Поэтому я решил попробовать добавить это поле вручную, но потом дошел до того, что не понимаю, как я могу?

Попробовал сoptions.GridFSUpload().SetMetadata(metadata) но я не понимаю логику этого, и интернет действительно минимален, в результате чего новый драйвер монго работает в GO.

Любой может подсказать, как добавить пользовательские поля в файл.документы?Как 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, как я хотел бы.

Спасибо за любую помощь

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Нет логики, которую вы пытаетесь понять.Причина, по которой вы не можете найти много информации о contentType в новом официальном драйвере mongo, заключается в том, что contentType устарел в спецификации gridfs задолго до того, как был написан драйвер.

Я должен признать документация gridfs не упоминает об этом.На самом деле официальный mongofiles cli все еще использует устаревший формат.

В спецификации все ясно:

Примечание: некоторые старые версии реализаций GridFS позволяли приложениям добавлять произвольные поля в документ коллекции файловна корневом уровне.Новые реализации GridFS не позволят этого , но должны быть готовы обрабатывать существующие документы коллекции файлов, которые могут иметь дополнительные поля.

И если вам нравится более подробный officialаргументация :

Почему не рекомендуется использовать contentType?

Большинство полей в документе коллекции файлов используются драйвером напрямую, за исключением: метаданных, contentType и псевдонимов.Вся информация, предназначенная исключительно для использования в приложении, должна быть включена в документ «метаданные».Пользователям GridFS, которые хотели бы хранить contentType для использования в своих приложениях, рекомендуется добавить поле «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 для длины файла tho.Новый драйвер ожидает, что это будет int64.Это должно быть хорошо для операций типа Find, которые работают только с коллекциями * .fiiles, но могут вызвать проблемы при загрузке таких файлов с новым официальным драйвером.

0 голосов
/ 16 февраля 2019

Вот пример 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)
}

Вот полный пример

...