当前位置: 首页 > 面试题库 >

使用GoLang mgo将PDF保存在MongoDb中

宋烨烁
2023-03-14
问题内容

我读过多个有关使用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');
         });

问题答案:

file通过返回Request.FormFile()类型为multipart.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

但是将大文件存储为文档的一部分并不是最佳/有效的方法。相反,看看在MongoDB的GridFS的也由支持mgoDatabase.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。添加适当的mgostruct标记:

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

或将所选字段从更改pdfpdfdata



 类似资料:
  • 问题内容: 绘图模块 主模块 我想将所有图plot1,plot2,plot3保存到一个PDF文件中。有什么办法可以实现?我不能在主模块中包含该功能。 有一个名为的函数,但只有将其与绘图模块一起放置时,该函数才起作用。还有其他方法可以实现吗? 问题答案: 没关系,有办法做到这一点。 ------绘图模块------ ----- mainModule ---- ----- mainModule ---

  • 提交表单后,我想将结果页保存为PDF格式。我怎么才能做到这一点。我对其他编程语言一窍不通,所以请帮助使用java代码。

  • 目前,我正在使用Scala开发一个具有Play2框架的后端服务器。我有以下问题: 我使用文件处理程序GridFS在MongoDB中保存像图像这样的文档。GridFs创建两个文件: fs.files(包含元数据)和fs.chunks(存储块) 但我想把图像保存在我自己的收藏中。所有图像都应该有一个数据库条目,如用户名和注释。我有两个解决问题的办法,但我需要帮助。 使用我自己的收藏: 如何使用Grid

  • 问题内容: noob Golang和Sinatra人在这里。我入侵了Sinatra应用程序,以接受从HTML表单发布的上传文件,并通过GridFS将其保存到托管的MongoDB数据库中。这似乎工作正常。我正在使用mgo驱动程序在Golang中编写相同的应用程序。 从功能上来说,它工作正常。但是在Golang代码中,我将文件读入内存,然后使用mgo将文件从内存写入MongoDB。这似乎比我同等的Si

  • 我想使用TypeORM将键值对存储到MongoDB。我的后端API是用NestJs制作的(不确定这是否重要)。键的类型为,值的类型为,因为我想将任何内容存储到此对象。 这是我的TypeForm数据库配置 我的映射实体不会自动生成密钥,因为我想自己设置它 当我想将一个新映射保存到数据库时,我运行这个逻辑(无论在哪里) 我得到这个错误 无法读取未定义的属性属性属性名称 执行数据库实体的功能时。似乎我无