Search code examples
node.jsmongodbfilegridfs-stream

stored files directly in mongodb with gridfs-stream


I need save some files like: images,video,pdf... into mongodb, so i use gridfs-stream and express.js

var file = req.files.file; 
req.pipe(gfs.createWriteStream({
    filename:file.originalname,
    mode:"w",
    chunkSize:1024*4,
    content_type:file.mimetype,
    root:"fs"
})
res.send(200);

for testing i use postman and set an POST request this way:

 POST /fs/upload HTTP/1.1
 Host: localhost:5000
 Cache-Control: no-cache

 ----WebKitFormBoundaryE19zNvXGzXaLvS5C
 Content-Disposition: form-data; name="file"; filename="epic.png"
 Content-Type: image/png


  ----WebKitFormBoundaryE19zNvXGzXaLvS5C

the problem is that this way just store the data of the file:

{
    "_id" : ObjectId("54d14ec5b102fe401519a3c1"),
    "filename" : "epic.png",
    "contentType" : "image/png",
    "length" : 0,
    "chunkSize" : 4096,
    "uploadDate" : ISODate("2015-02-03T22:42:14.730Z"),
    "aliases" : null,
    "metadata" : null,
    "md5" : "993fb9ce262a96a81c79a38106147e95"
}

but not the content i mean de binary data for it, into mongodb is store for it the propety length is equal to 0, bacause has not any chunks in fs.chucks.


Solution

  • Reading in blogs found the answer to streaming data directly at database with express.js,gridfs-stream.js and multer middleware that way:

    var multer = require('multer');
    
    app.post('/fs/upload', multer({
        upload: null,// take uploading process 
    
        onFileUploadStart: function (file) {
            //set upload with WritableStream        
            this.upload = gfs.createWriteStream({
                filename: file.originalname,
                mode: "w",
                chunkSize: 1024*4,
                content_type: file.mimetype,
                root: "fs"
            });
         },
    
         onFileUploadData: function (file, data) {
            //put the chucks into db 
            this.upload.write(data);
         },
    
         onFileUploadComplete: function (file) {
            //end process 
            this.upload.on('drain', function () {
                this.upload.end();
            });
         }
    }), function (req, res) {
       res.sendStatus(200);
    });
    

    For testing this:

    app.route('/fs/download/:file').get(function (req, res) {
       var readstream = gfs.createReadStream({_id: req.params.file});
       readstream.pipe(res);
    });