FileStream из busboy в MongoDB - PullRequest
       32

FileStream из busboy в MongoDB

0 голосов
/ 27 марта 2019

Итак, у меня есть входящий FileStream от busboy, который я хочу сохранить в MongoDB. Я думаю, что мне нужно иметь его как File или какой-то буфер, чтобы иметь возможность его сохранить. Я уверен, что мог бы сделать это, сначала сохранив его на диск, используя fs, а затем прочитав его, но это кажется громоздким. Это мой полный код маршрута:

// Upload a new study plan
router.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 ]

1 голос
/ 02 апреля 2019

Нет необходимости сохранять ваш файл на диск, вы можете транслировать его напрямую с busboy на 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.

0 голосов
/ 07 апреля 2019

Так что, хотя ответ Михала, вероятно, не неправильный, это было не то, что я хотел. Наконец-то я нашел решение, используя объект 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);
});
...