Biosopher
Biosopher

Reputation: 616

Read/write binary data to MongoDB in Node.js

I've been able to successfully write binary data (an image) to MongoDB in Node.js. However I can't find clear documentation on how to read it back.

Here's how I'm writing the image to MongoDB:

var imageFile = req.files.myFile;
var imageData = fs.readFileSync(imageFile.path);

var imageBson = {};
imageBson.image = new db.bson_serializer.Binary(imageData);
imageBson.imageType = imageFile.type;

db.collection('images').insert(imageBson, {safe: true},function(err, data) {

I'd appreciate any pointers on reading the image from Mongo using Node. I'm assuming there's a function like "db.bson_deserializer...". Thanks!

Upvotes: 4

Views: 7249

Answers (2)

toddmo
toddmo

Reputation: 22416

The MongoDB part isn't complicated. Once a Buffer is in the model, just let the db save it. MongoDB converts that into BinData. 80% of this code is just getting an image into and out of a PNG file.

People say don't store images in MongoDB, but icons/thumbs are tiny. Having said that, it might be a good idea to have an icons collection and only store them once using a hash of the image data as the _id.

model class example

class MyModel {
    _icon: Buffer
    get icon(): Buffer {
        return this._icon
    }
    set icon(value: Buffer) {
        this._icon = value
    }
}

image helper

static async loadImage(url: string) {
    var files = require('../lib/files')
    var buffer = await files.urlContents(url, true)
    return buffer
}

static async saveImage(image: Buffer, path: string) {
    var files = require('../lib/files')
    files.write(path, image.buffer)
    return path
}

files helper

function urlResponse(url, binary) {
    var request = require("request")
    if (binary)
        request = request.defaults({ encoding: null })
    return new Promise(function (resolve, reject) {
        request(url, function (error, res, body) {
            if (error || res.statusCode !== 200 || body.includes('Incomplete response received from application'))
                resolve({ statusCode: res?.statusCode !== 200 ? (res?.statusCode || 500) : 500 });
            else
                resolve(res);
        });
    });
}

async function urlContents(url, binary) {
    var res = await urlResponse(url, binary)
    if (binary)
        return Buffer.from(res.body)
    else
        return res.body
}


function write(fileName, contents) {
    fs.writeFileSync(fileName, contents)
}

mongodb helper

// ...saving

myModel.icon = loadImage('http://some.site.com/image.png')
collection.insertOne(myModel)

// ..getting
myModel = collection.findOne(query) // now myModel contains icon
saveImage(myModel.icon, '/home/toddmo/pictures/wow.png')

Upvotes: 0

Biosopher
Biosopher

Reputation: 616

Found the answer:

        var imageFile = req.files.myFile;
    fs.exists(imageFile.path, function(exists)  {

        if(exists)
        {
            console.log("File uploaded: " + util.inspect(imageFile));
            fs.readFile(imageFile.path, function(err, imageData) {
                if (err) {
                    res.end("Error reading your file on the server!");
                }else{
                    //when saving an object with an image's byte array
                    var imageBson = {};
                    //var imageData = fs.readFileSync(imageFile.path);
                    imageBson.image = new req.mongo.Binary(imageData);
                    imageBson.imageType = imageFile.mimetype;
console.log("imageBson: " + util.inspect(imageBson));

                    req.imagesCollection.insert(imageBson, {safe: true},function(err, bsonData) {

                        if (err) {
                            res.end({ msg:'Error saving your file to the database!' });
                        }else{
                            fs.unlink(imageFile.path); // Deletes the file from the local disk
                            var imageBson = bsonData[0];
                            var imageId = imageBson._id;
                            res.redirect('images/' + imageId);
                        }
                    });
                }
            });
        } else {
            res.end("Oddly your file was uploaded but doesn't seem to exist!\n" + util.inspect(imageFile));
        }
    });

Upvotes: 4

Related Questions