为了账号安全,请及时绑定邮箱和手机立即绑定

从Busboy到MongoDB的FileStream

从Busboy到MongoDB的FileStream

陪伴而非守候 2021-03-29 13:10:58
所以我有一个从busboy传入的FileStream,我想保存到MongoDB。我想我需要将其作为一个File或某种缓冲区来保存它。我敢肯定,可以通过使用以下方法将其保存到磁盘fs然后读取来完成,但这似乎很麻烦。到目前为止,这是我的完整路由代码:// Upload a new study planrouter.route("/add").post((req, res, next) => {    let busboy = new Busboy({headers: req.headers});    // A field was recieved    busboy.on('field', function (fieldname, val, valTruncated, keyTruncated) {        if (req.body.hasOwnProperty(fieldname)) { // Handle arrays            if (Array.isArray(req.body[fieldname])) {                req.body[fieldname].push(val);            } else {                req.body[fieldname] = [req.body[fieldname], val];            }        } else { // Else, add field and value to body            req.body[fieldname] = val;        }    });    // A file was recieved    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {        const saveTo = path.join('.', filename);        let readFile = null;        file.on("data", () => {            console.log("Got file data!");        })        file.on("end", () => {            //How do I save the file to MongoDB?        })    });    // We're done here boys!    busboy.on('finish', function () {        //console.log(req.body);        console.log('Upload complete');        res.end("That's all folks!");    });    return req.pipe(busboy);});我想附加{"pdf": file}到我req.body的剩余数据中...
查看完整描述

2 回答

?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

无需将文件保存到磁盘,您可以busboy使用某种流接口直接将其从流传输到mongo-我不确定您希望如何保存文件,但是如果这只是一个简单的文件结构,我想您应该使用Mongo的GridFS。


我假设您是从某个地方获得连接和客户端的,所以我们就使用它。我们需要一个GridFS存储桶:


const db = client.db(dbName);

const bucket = new mongodb.GridFSBucket(db);

当我们要保存文件时,将使用它:


    // A file was recieved

    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {

        const saveTo = path.join('.', filename);

        // here we PIPE the file to DB.

        file.pipe(bucket.openUploadStream(saveTo));

    });

现在还有一个问题是何时实际保存文件-因为这是异步完成的。因此,我们需要保持这样的运行操作计数:


    // place this in the request callback.

    // here's our counter - we'll increment it for each operation started.

    let ops = 0;

    const dec = () => --ops || res.end("That's all folks!");

现在,我们将上面的代码稍作更改,以便在文件保存到Mongo中之前不会做出响应:


    // A file was recieved

    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {

        ops++; // we increment ops for each file saved

        const saveTo = path.join('.', filename);

        // here we PIPE the file to DB (pass the db and collection here).

        file.pipe(bucket.openUploadStream(saveTo))

            .on('finish', dec);

    });


    ops++; // we're waiting for finish of the request also so another increment

    busboy.on('finish', dec);

如您所见,每次文件上传开始时,我们都会增加操作次数,完成后我们会减少操作次数。该||运营商将执行res.end时的方法ops达到0。


查看完整回答
反对 回复 2021-04-08
?
翻阅古今

TA贡献1780条经验 获得超5个赞

因此,尽管Michal的答案可能没有错,但这并不是我所追求的。我终于找到了使用该Buffer对象的解决方案。这是我的代码:


router.route("/add").post((req, res, next) => {

    let busboy = new Busboy({headers: req.headers});

    let buffers = [];


    // A field was recieved

    busboy.on('field', function (fieldname, val, valTruncated, keyTruncated) {


        if (req.body.hasOwnProperty(fieldname)) { // Handle arrays

            if (Array.isArray(req.body[fieldname])) {

                req.body[fieldname].push(val);

            } else {

                req.body[fieldname] = [req.body[fieldname], val];

            }

        } else { // Else, add field and value to body

            req.body[fieldname] = val;

        }

    });


    // A file was recieved

    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {


        file.on("data", (data) => {

            buffers.push(data);

        });


        file.on("end", () => {

            req.body[fieldname] = Buffer.concat(buffers);

        });

    });


    // We're done here boys!

    busboy.on('finish', function () {

        console.log(req.body);


        const plan = new StudyPlan(req.body);

        plan.save()

            .then(_ => console.log("YEEAEH!"))

            .catch(err => {console.log(err);});


        res.end();

    });

    return req.pipe(busboy);

});


查看完整回答
反对 回复 2021-04-08
  • 2 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号