项目中有些文档的大小超过了16M,超出了mongodb一个文档的最大大小,于是就将文档对象转JSON字节数组后,将字节存成文件格式。
环境go版本:go1.15.1
mongodb驱动包: go\pkg\mod\go.mongodb.org\[email protected]
文件的存储
其实就是两个普通的集合Collection.默认分别为fs.files和fs.chunks
fs也能替换成自定义命名的
如下图
package dao
import (
"bytes"
"local.com/util/logger"
"go.mongodb.org/mongo-driver/mongo/gridfs"
"go.mongodb.org/mongo-driver/mongo/options"
)
func getGridfsBucket(collName string) *gridfs.Bucket {
var bucket *gridfs.Bucket
// 使用默认文件集合名称
if collName == "" || collName == options.DefaultName {
bucket, _ = gridfs.NewBucket(MongoDatabase)
} else {
// 使用传入的文件集合名称
bucketOptions := options.GridFSBucket().SetName(collName)
bucket, _ = gridfs.NewBucket(MongoDatabase, bucketOptions)
}
return bucket
}
// 上传文件
// collName:文件集合名称 fileID:文件ID,必须唯一,否则会覆盖
// fileName:文件名称 fileContent:文件内容
func GridfsUploadWithID(collName, fileID, fileName string, fileContent []byte) error {
bucket := getGridfsBucket(collName)
err := bucket.UploadFromStreamWithID(fileID, fileName, bytes.NewBuffer(fileContent))
if err != nil {
logger.Error(err)
return err
}
return nil
}
// 下载文件
// 返回文件内容
func GridfsDownload(collName, fileID string) (fileContent []byte, err error) {
bucket := getGridfsBucket(collName)
fileBuffer := bytes.NewBuffer(nil)
if _, err = bucket.DownloadToStream(fileID, fileBuffer); err != nil {
logger.Error(err)
return nil, err
}
return fileBuffer.Bytes(), nil
}
// 删除文件
func GridfsDelete(collName, fileID string) error {
bucket := getGridfsBucket(collName)
if err := bucket.Delete(fileID); err != nil && err != gridfs.ErrFileNotFound {
logger.Error(err)
return err
}
return nil
}
调用代码
// 因某些文档数据长度大于16M,所以存到文件中
// 先删除文件
fileID="xxx"
_ = dao.GridfsDelete(fbSeasonStatsDetailAPI, fileID)
jsonBytes, _ := json.Marshal(list.Results)
_ = dao.GridfsUploadWithID(fbSeasonStatsDetailAPI, fileID, fileID+".json", jsonBytes)
驱动包中提供的DEMO
可以查看驱动包下的示例文件来实现其他文件操作相关的方法
示例文件路径如下
go\pkg\mod\go.mongodb.org\[email protected]\mongo\gridfs\gridfs_examples_test.go