Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing some small (under 1MB) files with MongoDB in NodeJS WITHOUT GridFS

I run a website that runs on a backend of nodeJS + mongoDB. Right now, I'm implementing a system to store some icons (small image files) that will need to be in the database.

From my understanding, it makes more sense NOT to use GridFS, since that seems to be tailored for either large files or large numbers of files. Since every file that I need to save will be well under the BSON maximum file size, I should be able to save them directly into a regular document.

I have 2 questions:

1) Is my reasoning correct? Is it ok to save image files within a regular mongo collection, as opposed to with GridFS? Is there anything I'm not considering here that I should be?

2) If my thought process is sound, how do I go about doing this? Could I do something like the following:

//assume 'things' is a mongoDB collection created properly using node-mongodb-driver  fs.readFile(pathToIconImage, function(err,image){   things.insert({'image':image}, function(err,doc){     if(err) console.log('you have an error! ' + err);   }); }); 

I'm guessing that there's probably a better way to do this, since mongoDB uses BSON and here I'm trying to save a file in JSON before I send it off to the database. I also don't know if this code will work (haven't tried it).

UPDATE - New Question

If I have a document within a collection that has three pieces of information saved: 1) a name, 2) a date, and 3) an image file (the above icon), and I want to send this document to a client in order to display all three, would this be possible? If not, I guess I'd need to use GridFS and save the fileID in place of the image itself. Thoughts/suggestions?

Best, and thanks for any responses,
Sami

like image 467
thisissami Avatar asked Jul 11 '12 22:07

thisissami


People also ask

Why do we need GridFS in MongoDB?

In MongoDB, use GridFS for storing files larger than 16 MB. In some situations, storing large files may be more efficient in a MongoDB database than on a system-level filesystem. If your filesystem limits the number of files in a directory, you can use GridFS to store as many files as needed.

Is MongoDB good for file storage?

Large objects, or "files", are easily stored in MongoDB. It is no problem to store 100MB videos in the database. This has a number of advantages over files stored in a file system. Unlike a file system, the database will have no problem dealing with millions of objects.

Is storing images in MongoDB a good idea?

Storing images is not a good idea in any DB, because: read/write to a DB is always slower than a filesystem. your DB backups grow to be huge and more time consuming. access to the files now requires going through your app and DB layers.


2 Answers

If your images truly are small enough to not be a problem with document size and you don't mind a little amount of extra processing, then it's probably fine to just store it directly in your collection. To do that you'll want to base64 encode the image, then store it using mongo's BinData type. As I understand it, that will then save it as a BSON bit array, not actually store the base64 string, so the size won't grow larger than your original binary image.

It will display in json queries as a base64 string, which you can use to get the binary image back.

like image 101
Tim Gautier Avatar answered Sep 23 '22 08:09

Tim Gautier


I have been looking for the same thing. I know this post is old , but perhaps i can help someone out there.

var fs = require('fs'); var mongo = require('mongodb').MongoClient; var Binary = require('mongodb').Binary;  var archivobin = fs.readFileSync("vc.exe");  // print it out so you can check that the file is loaded correctly console.log("Loading file"); console.log(archivobin);  var invoice = {}; invoice.bin = Binary(archivobin);  console.log("largo de invoice.bin= "+ invoice.bin.length()); // set an ID for the document for easy retrieval invoice._id = 12345;    mongo.connect('mongodb://localhost:27017/nogrid', function(err, db) {   if(err) console.log(err);      db.collection('invoices').insert(invoice, function(err, doc){     if(err) console.log(err);   // check the inserted document     console.log("Inserting file");     console.log(doc);      db.collection('invoices').findOne({_id : 12345}, function(err, doc){       if (err) {         console.error(err);         }        fs.writeFile('vcout.exe', doc.bin.buffer, function(err){           if (err) throw err;           console.log('Sucessfully saved!');     });      });   }); }); 
like image 26
uajov6 Avatar answered Sep 24 '22 08:09

uajov6