注:仅仅是功能的实现不考虑是否最优(希望是).
mongoose.js
.const mongoose = require('mongoose')
const env = require('../enviroment/env')
mongoose.connect(env.mongoURL, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false
})
mongoose.connection.on('error', (err) => {
console.error('数据库连接出错:' + err)
})
mongoose.connection.on('connected', () => {
console.log('数据库已连接:' + env.mongoURL)
})
module.exports = mongoose
需要处理post
文件中间件:connect-busboy
,方便直接获取文件流.
const busboy = require('connect-busboy');
app.use(busboy());
具体处理请求controller :
try {
const busboy = req.busboy;
req.pipe(busboy);
let file = await fileService.upLoad(busboy, req)
res.send(file);
} catch (error) {
res.status(500).send(error.toString());
}
以上步骤已经可以获取上传的文件流,接下来需要将流写入到mongodb.
因为mongodb的文件存储不是通过自定义model来写入的,必须用到mongoose 的配置文件,进行文件操作(个人理解).
const mongoose = require('../db/mongoose')
const conn = mongoose.connection;
busboy.on('file', async function (fieldname, file, filename, encoding, mimetype) {
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
});
let user = req.user
//自己添加的信息
const metadata = {
ownerID: user._id,
}
let bucketStream = bucket.openUploadStream(filename, { metadata })
bucketStream.on("error", async (e) => {
await removeChunks(bucketStream);
throw new Error('SaveBlogImg BucketStream Error')
})
req.on("aborted", async () => {
console.log("Upload Request Cancelling...");
await removeChunks(bucketStream);
})
file.pipe(bucketStream)
// file:数据库保存后的内容
bucketStream.on("finish", async (file) => {}
})
通过以上步骤已经可以保存上传的文件到mongodb中,使用可视化工具查看数据库可以看到新添加的集合fs.chunks
与fs.files
,还有一个GridFS Bucket
.只要删除了后者的文件内容fs.chunks
与fs.files
里面对应的文件都会被删除.注意力集中到fs.files
,平时我们操作文件都是通过这个集合来入手的.
可以通过fs.files
查询到文件内容的id与name,再通过它获取文件.
const ObjectID = require('mongodb').ObjectID
let bucket = new mongoose.mongo.GridFSBucket(conn.db, {
chunkSizeBytes: 1024 * 255
})
let readeStream = bucket.openDownloadStream(ObjectID(id))
使用到文件保存处理更多的是涉及图片的内容,配合mongodb读取图片内容可以使用npm工具sharp
与concat-stream
.前者可以处理图片的大小,后者可以把stream转成buffer类型,当然它们的功能不仅仅如此,更多的需要你去发现.