使用 GoLang mgo 在 MongoDb 中保存 pdf
Saving pdf in MongoDb using GoLang mgo
我阅读了多个关于使用 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 表单接收)?
感谢阅读! :)
Update:
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');
});
Request.FormFile()
is of type multipart.File
返回的file
是:
type File interface {
io.Reader
io.ReaderAt
io.Seeker
io.Closer
}
它实现了io.Reader
, so you can simply read its content e.g. with ioutil.ReadAll()
:
data, err := io.ReadAll(file)
// Handle error
然后:
dbSchoolPojo.Pdfdata = data
但是将大文件作为文档的一部分存储并不是最佳/高效的。相反,看看 MongoDB GridFS that is also supported by mgo
: Database.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
,您还可以保存文件而无需先将其所有内容读入内存,如果您"stream"将文件内容放入mgo.GridFile
, as it implements io.Writer
. Call 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)
您 select 要检索的 pdf
字段,但是您在 MongoDB 中的文档没有该字段:
type dbSchool struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
...
Pdfdata []byte `json:"pdf"`
...
}
此类型定义将导致具有 pdfdata
字段,但没有 pdf
。添加正确的 mgo
结构标签:
type dbSchool struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
...
Pdfdata []byte `json:"pdf" bson:"pdf"`
...
}
或将 selected 字段从 pdf
更改为 pdfdata
。
我阅读了多个关于使用 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 表单接收)?
感谢阅读! :)
Update:
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');
});
Request.FormFile()
is of type multipart.File
返回的file
是:
type File interface {
io.Reader
io.ReaderAt
io.Seeker
io.Closer
}
它实现了io.Reader
, so you can simply read its content e.g. with ioutil.ReadAll()
:
data, err := io.ReadAll(file)
// Handle error
然后:
dbSchoolPojo.Pdfdata = data
但是将大文件作为文档的一部分存储并不是最佳/高效的。相反,看看 MongoDB GridFS that is also supported by mgo
: Database.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
,您还可以保存文件而无需先将其所有内容读入内存,如果您"stream"将文件内容放入mgo.GridFile
, as it implements io.Writer
. Call 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)
您 select 要检索的 pdf
字段,但是您在 MongoDB 中的文档没有该字段:
type dbSchool struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
...
Pdfdata []byte `json:"pdf"`
...
}
此类型定义将导致具有 pdfdata
字段,但没有 pdf
。添加正确的 mgo
结构标签:
type dbSchool struct {
ID bson.ObjectId `json:"id" bson:"_id,omitempty"`
...
Pdfdata []byte `json:"pdf" bson:"pdf"`
...
}
或将 selected 字段从 pdf
更改为 pdfdata
。