Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I retrieve a Binary file from MongoDB after storing it?

I store the file similar to the following:

var pdfBinary = fs.readFileSync("myfile.pdf");
var invoice = {};
invoice.pdf = new mongo.Binary(pdfBinary);

I then insert the above document into MongoDB. Then I try to retrieve it similar to the following:

    collection.findOne({}, function(err, retrievedPDF) {
        fs.writeFile("myretrieved.pdf", retrievedPDF.pdf.buffer, function(err) {
            ....
        });

    }); 

It comes out as a zero byte file. If I console.log the stored file it looks like the following:

{ pdf: 
 { _bsontype: 'Binary',
   sub_type: 0,
   position: 0,
   buffer: <Buffer > },
_id: 53af545681a59758611937d7 }

I've gone through the documentation I find it somewhat confusing. What am I doing wrong that I cannot store/retrieve the file?

like image 915
Hoa Avatar asked Jun 28 '14 23:06

Hoa


People also ask

Can you store binary in MongoDB?

MongoDB stores objects in a binary format called BSON. BinData is a BSON data type for a binary byte array. However, MongoDB objects are typically limited to 16MB in size. To deal with this, files are "chunked" into multiple objects that are less than 255 KiB each.

Can MongoDB support the storage and retrieval of image and video?

So for storing an image in MongoDB, we need to create a schema with mongoose. For that create the file `model. js` file and define the schema. The important point here is that our data type for the image is a Buffer which allows us to store our image as data in the form of arrays.

Can we store blob in MongoDB?

In MongoDB, you can use the BSON binary type to store any kind of binary data. This data type corresponds to the RDBMS BLOB (binary large object) type, and it's the basis for two flavors of binary object storage provided by MongoDB. The first uses one document per file and is best for smaller binary objects.

What is the name of storage object where all documents of MongoDB is stored?

MongoDB stores documents in collections. Collections are analogous to tables in relational databases.


2 Answers

You're trying to read an empty file. Check your code for loading the file from disk and check the PDF file.

The empty Binary file will look like this:

> console.log(new mongodb.Binary(""));
{ _bsontype: 'Binary',
  sub_type: 0,
  position: 0,
  buffer: <Buffer > }

The Binary that has a content would look something like:

{ _bsontype: 'Binary',
     sub_type: 0,
     position: 7867,
     buffer: <Buffer 25 50 44 46 2d 31 2e 34 0a 25 c3 a4 c3 bc c3 b6 c3 ...> }

Here's a complete example that worked for me:

var fs = require('fs');
var mongo = require('mongodb').MongoClient;

var pdfBinary = fs.readFileSync("testout.pdf"); 
// print it out so you can check that the file is loaded correctly
console.log("Loading file");
console.log(pdfBinary);

var invoice = {};
invoice.pdf = new mongodb.Binary(pdfBinary);
// set an ID for the document for easy retrieval
invoice._id = 12345; 

mongo.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
  if(err) console.log(err);

  db.collection('invoices').insert(invoice, function(err, doc){
    // 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('testout.pdf', doc.pdf.buffer, function(err){
          if (err) throw err;
          console.log('Sucessfully saved!');
      });
    });
  });
});

I added console.log() commands so you can easily see where is the problem.

like image 187
Christian P Avatar answered Oct 19 '22 13:10

Christian P


Certainly looks like something has gone wrong in the save. Here is a complete working example to compare to:

var fs = require('fs'),
    mongo = require('mongodb'),
    MongoClient = mongo.MongoClient,
    ObjectId = mongo.ObjectID,
    Binary = mongo.Binary;


MongoClient.connect('mongodb://localhost/fs',function(err,db) {

  var name = "receptor.jpg";
  var binData = fs.readFileSync(name);
  var object = {};
  object.name = name;
  object.data = new Binary(binData);

  db.collection("test").findAndModify(
    { name: name },
    [],
    object,
    { upsert:true },
    function(err,data,newObj) {

      if ( data == null ) {
        console.log(newObj);
      } else {
        console.log(data);
      }

      db.collection("test").findOne({ name: name },function(err,data) {

        fs.writeFile("ouput.jpg",data.data.buffer,function(err) {
          console.log("done");
        });
    });
  });
});
like image 27
Neil Lunn Avatar answered Oct 19 '22 12:10

Neil Lunn