Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strategy for uploading images to mongoDB Atlas with multer?

My goal is to be able to upload images to mongoDB Atlas with the use of Multer. Currently, I have set up an example with express-generator, with the following relevant files:

app.js:

// ...
var app = express();

//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'mongodb+srv://username:[email protected]/test?retryWrites=true&w=majority';
mongoose.connect(mongoDB, { useNewUrlParser: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// ...

index.js:

var express = require('express');
var router = express.Router();
var multer = require("multer");
var fs = require("fs");
var upload = multer({ dest: 'uploads/' })
var Image = require('../models/image');

// GET for image form
router.get("/image/create", function(req, res, next) {
    res.render("create_image", {title: "Create Image"});
});

// Uploading image to mongoDB Atlas
router.post("/image/create", upload.single("image"), function(req, res, next) {
    var image = new Image({
        name: req.body.image_name
    });
    image.img.data = fs.readFileSync(req.file.path);
    image.img.contentType = "image/jpg";
    image.save(function(err) {
        if (err) { return next(err); }
        res.redirect("/");
    });
});

// Show some random image
router.get("/image", function(req, res, next) {
    Image.findOne({}, function(err, image) {
        if (err) { return next(err); }
        res.contentType(image.img.contentType)
        res.send(image.img.data);
    });
});

image.js (Image schema):

var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var ImageSchema = new Schema(
    {
        name: {type: String, required: true, max: 100},
        img: {data: Buffer, contentType: String}
    }
);

module.exports = mongoose.model("Image", ImageSchema);

And finally the form for creating images create_image.pug:

extends layout

block content
    h1= title

    form(action="" method="POST" enctype="multipart/form-data")
        label(for="image_name") Name of Image:
        input#image_name.form-control(type="text" placeholder="Name of image" name="image_name" required="true")
        input(type="file" name="image")
        button(type='submit') Submit

This works sort of fine, in that the image is stored in MongoDB Atlas, but it also stores images locally. Now from a production standpoint this is not a good idea, as the project would get large. However I can't seem to figure out the right way of doing this thing?

Could someone tell me the right way of doing this, so that I only store images on MongoDB Atlas, and not locally? Also possibly tell me if I have this whole thing the wrong way round, and should be doing this in a completely different way?

like image 242
Norse Avatar asked Sep 02 '25 04:09

Norse


1 Answers

If you don't want to store images locally, use MemoryStorage as Multer Storage.

var storage = multer.memoryStorage()
var upload = multer({ storage: storage })

When using memory storage, the file info will contain a field called buffer that contains the entire file. So you don't have to call fs.readFileSync. You can access buffer with req.file.image.buffer and assign image data;

image.img.data = req.file.image.buffer;
like image 148
Nisan Coşkun Avatar answered Sep 05 '25 01:09

Nisan Coşkun