【问题标题】:Saving pdf in MongoDb using GoLang mgo使用 GoLang mgo 在 MongoDb 中保存 pdf
【发布时间】:2017-10-17 07:36:32
【问题描述】:

我阅读了多篇关于使用 mgo 保存文件的博客,但无法找到满足以下特定需求的解决方案,请大喊大叫!

下面在 MongoDb 中插入对象:

var dbSchoolPojo dbSchool
i := bson.NewObjectId()
dbSchoolPojo.ID = i
coll := db.C("school")
coll.Insert(&dbSchoolPojo)

以下可以获取文件:

file, handler, err := r.FormFile("pdf") //Able to get file from r *http.Request

现在,在插入对象之前,我需要设置上面的文件,如:

dbSchoolPojo.pdf = file.Bytes(); //Of course Bytes() is invalid method

我的结构对象:

type dbSchool struct {
    ID  bson.ObjectId  `json:"id" bson:"_id,omitempty"`
    ...
    Pdf  []byte  `json:"pdf" bson:"pdf"`
    ...
}

用外行的话来说,问题是:如何使用 mgo 驱动程序通过 GoLang 结构在 mongoDb 中插入文件(从 HTML 表单接收)?

感谢阅读! :)


更新:

PDF 存储在 MongoDB 中,如下所示:

Binary('EWHKDSH876KJHlkjdswsddsfsd3232432njnjkn2dljDSFSDFIJSFD333...')

以下代码可以正常工作,但不提供 PDF 文件:

func DownloadPdf(w http.ResponseWriter, r *http.Request, db mongoDB) {
    var school dbSchool
    coll := db.C("schools")

    incomingId = "59e6404e2f68182a74610f19"; //This mongo DB _id is received from GET URL request

    err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}).
        Select(bson.M{"pdf": 1}).One(&school)
    if err != nil {
        serve404(w, r, db)
        return
    }

    buffer := school.Pdf
    w.Header().Set("Content-Disposition", "attachment; filename=abc.pdf")
    w.Header().Set("Content-Type", "application/pdf")
    w.Header().Set("Content-Length", strconv.Itoa(len(buffer)))

    if _, err := w.Write(buffer); err != nil {
        log.Println("unable to serve image.") //This line is not executed
    }
}

请求内容的jQuery代码:

      $(".downloadPdfFile").click(function() {
            var domain = document.location.origin;
            window.open(domain+'/brochure/59e6404e2f68182a74610f19', '_blank');
         });

【问题讨论】:

    标签: jquery mongodb file go mgo


    【解决方案1】:

    Request.FormFile() 返回的filemultipart.File 类型,即:

    type File interface {
        io.Reader
        io.ReaderAt
        io.Seeker
        io.Closer
    }
    

    它实现了io.Reader,所以你可以简单地阅读它的内容,例如ioutil.ReadAll():

    data, err := io.ReadAll(file)
    // Handle error
    

    然后:

    dbSchoolPojo.Pdfdata = data
    

    但将大文件存储为文档的一部分并不是最佳/高效的。相反,请查看mgo 也支持的MongoDB GridFSDatabase.GridFS()

    以下是在 MongoDB GridFS 中存储文件的方法(示例取自 GridFS.Create()):

    func check(err error) {
        if err != nil {
            panic(err.String())
        }
    }
    file, err := db.GridFS("fs").Create("myfile.txt")
    check(err)
    n, err := file.Write([]byte("Hello world!"))
    check(err)
    err = file.Close()
    check(err)
    fmt.Printf("%d bytes written\n", n)
    

    使用GridFS,如果您将文件内容“流式传输”到mgo.GridFile,您还可以保存文件而不必先将其所有内容读入内存,因为它实现了io.Writer。拨打io.Copy():

    // ...
    file, handler, err := r.FormFile("pdfFile")
    
    // ...
    mongoFile, err := db.GridFS("fs").Create("somepdf.pdf")
    check(err)
    
    // Now stream from HTTP request into the mongo file:
    written, err := io.Copy(mongoFile, file)
    // Handle err
    
    err = mongoFile.Close()
    check(err)
    

    编辑:更新回答您的更新

    当您提供 PDF 时,您以错误的方式查询文档:

    err := coll.Find(bson.M{"_id": bson.ObjectIdHex(incomingId)}).
        Select(bson.M{"pdf": 1}).One(&school)
    

    您选择了pdf 字段进行检索,但您在 MongoDB 中的文档没有该字段:

    type dbSchool struct {
        ID  bson.ObjectId  `json:"id" bson:"_id,omitempty"`
        ...
        Pdfdata  []byte  `json:"pdf"`
        ...
    }
    

    此类型定义将导致具有pdfdata 字段,但没有pdf。添加正确的mgo struct 标签:

    type dbSchool struct {
        ID  bson.ObjectId  `json:"id" bson:"_id,omitempty"`
        ...
        Pdfdata  []byte  `json:"pdf" bson:"pdf"`
        ...
    }
    

    或将所选字段从pdf 更改为pdfdata

    【讨论】:

    • 你好@icza,它成功了!还有一个问题:现在我在 struct 对象中获取字节数据,下一步是将这些数据转换为 pdf 文件并允许用户通过网络浏览器下载它。你能帮忙吗?
    • @NikhilJoshi 开始查看这个问题:PDF download is not working from serverside in golang
    • 你好@icza,我试过了,但它不能完全工作。请参阅原帖中的更新。
    • 有错字,它只是 Pdfdata,请参阅编辑的更新部分。我错过了什么吗?
    • @NikhilJoshi 请仔细阅读我的回答。 MongoDB 将使用一个名为"pdfdata" 的字段,带有小写字母,但您使用带有大写字母的"Pdfdata" 进行投影。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 2012-10-20
    • 2018-07-28
    • 2014-08-26
    相关资源
    最近更新 更多