3

How do I get a binary field from an existing mongo db document?

At the MongoDB console, if I do a find for the record of choice I get this:

{_id:ObjectId("1234"),"cover_data" : BinData(2,"ozkAAP/Y/+AAEEpGSUYAAQEBAJYAlgAA/+IFpElDQ19QUk9GSUxFAAEBAAAFlGFwcGwCIAAAbW50clJHQiBYWVogB9kAAgAZAAsAGgALYWNzcEFQUEwAAAAAYXBwbAAAAAAAAAAAAAAAAAAAAAAAAPbWAAEAAAA ..... )

In python on our web server when we do a find with pymongo it gets that field as binary and json_pickle seems to turn it to base64 automatically and alas the image looks great when sent back to the client. When I compare the generated base64 to the node.js mongo driver it's completely different and doesn't display the image properly.

Here is the code for Node.JS:

cb = function(comp) {
    thumb_buffer = new Buffer(comp.thumbnail_data.value(),'binary');
    comp.thumbnail_data = thumb_buffer.toString('base64');
}

In the examples and test cases here: https://github.com/christkv/node-mongodb-native I don't see any example of what I'm trying to do. There seem to be BSON deserializers and a BinaryParser that is used in the case of a whole BSON object. I tried it for just the one field and got a segmentation faults.

Running list of things I've tried:

    mongo_compositions.find {_id:{$in:ids}},{},(err,compositions) -> 
            for comp in compositions
                do(comp) =>
                    thumb_buffer = comp.thumbnail_data.value(true)
                    test_buffer = Binary(thumb_buffer)
                    console.log test_buffer
                    console.log test_buffer.toString('base64')
                    #thumb_buffer = BSON.deserialize thumb_buffer
                    #thumb_buffer.write(comp.thumbnail_data.value(true))
                    #comp.thumbnail_data = thumb_buffer.toString('base64')
                    #cover_buffer = new Buffer(comp.cover_data.value(),'binary')
                    #console.log thumb_buffer.toString('base64')
                    #console.log "#{comp.composition_author} - #{comp.thumbnail_data.length}"
                    #comp.cover_data = cover_buffer.toString('base64')
2
  • There is no question posed here. Are you trying to read a file out of GridFS using node-mongodb-native? Commented Nov 8, 2011 at 0:00
  • No, I'm trying to read a binary field off an object. I want the cover_data field to contain base64 string. In the DB the type is BinData(2). Commented Nov 8, 2011 at 0:18

2 Answers 2

4

I am a bit confused on what you are trying to do. When selecting/inserting binary elements into MongoDB using node-mongodb, you must use binary bson object.

var buffer = new Buffer(); /* your binary data */
var binary = client.bson_serializer.Binary( buffer );
var myDoc = {
    binaryField: binary;
}
//And for when selecting the document
var buffer = myDoc.binaryField.value( true ); 

Set the toString argument to true to select it as a Buffer; false to return as "binary", but as the manual says, it should be avoided towards the buffer object.

To translate from a buffer to base64:

buffer.toString('base64');
Sign up to request clarification or add additional context in comments.

1 Comment

It tried the buffer = myDoc.binaryField.value(true) and buffer.toString('base64') and it just throws binary garbage everywhere. In the shell if I do: find().next().myBinaryField.length() it's 6800 in length. If I do the way you describe up there in node it's 4700. It works in Python, just not in Node.
2

As it turns out for: myDoc.binaryField.value( true ); The first 4 bytes (32-bits) are the big endian length of the size of the data. If you read from past those 4 bytes the buffer then that will end up being the data.

In my case the start of the data looked like this in hex:

63 12 00 00 ff d8 ff e0 00 10 4a 46

The python data looked like this:

ff d8 ff e0 00 10 4a 46

Binary = client.bson_serializer.Binary
binary = new Binary(myDoc.binaryField.value( true ))
buffer = new Buffer(binary.toString(),'binary')
length_buf = buffer.slice(0,4)
length = length_buf[3] << 32 | length_buf[2] << 16 | length_buf[1] << 8 | length_buf[0]
buffer.slice(4).slice(0,length).toString(enc)

1 Comment

or you could just use mydoc.binaryField.buffer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.