Store Images in MongoDB

You may use a database to store pictures and other tiny images in a database table. Such picture files may be processed considerably more efficiently on a file server.
However, when image data is stored in a binary field, it is only accessible to applications that stream raw picture data to and from that field.
The MongoDB GridFS specification is a viable choice for storing considerably huge files in MongoDB. It ensures that the file is broken down into manageable bits and saved in a database.
The process for saving and retrieving binary files to and from MongoDB is explained in this article.
The GridFS in MongoDB
GridFS is a standard for storing and retrieving larger files than the 16 MB limit set by BSON. GridFS splits a file into sections or chunks and keeps each piece separate rather than storing it as a single document.
Store a metadata JSON document for each item in Couchbase, along with a tiny thumbnail picture at most.
That document contains information about that object in your application that you need immediately and reference purpose-built object storage such as S3, a file system, or HDFS. So, you will have the best of both worlds.
In this MongoDB tutorial, the problem of storing images in the MongoDB database is discussed in detail. Also, you will learn the different ways you can keep the image and efficiently retrieve the images from the MongoDB database.
Store Images in MongoDB Using GridFS
You can store the images in the MongoDB database by creating a schema with Mongoose. The schema is defined by creating a file, model.js .
The data type Buffer is used for storing the images in the database form of arrays.
- GridFS: Using GridFS API, you will be able to store large-sized images. This API helps you store the large file into small chunks (255KiB) and store it into separate documents in an «fs.chunks» collection.
- Inline: In this, smaller images (16MB) can be stored into MongoDB documents using binary data.
- Reference: In this, only image references are stored in the database, and you can also store images in API or some file system.
Because huge files are difficult for end-users to access, storing the binary files in a database makes it easier to distribute across numerous sites. It is worth noting that before saving photos in a database, you should consider the benefits.
Store Images in MongoDB Using Python
This section will discuss how to store images in MongoDB via Python.
It is a file system storing and retrieving extensive data such as photos, audio, and movies. In this case, there is a bias to store data in a MongoDB collection.
In addition, it can store files larger than the 16MB scale limit.
The Python library PyMongo connects with the MongoDB database. Various functionality actions, such as retrieving results, writing and deleting data, and running the database, are available.
You may now use the library when it has been installed. But, first, import the library, connect to the server to use MongoDB in Python, and build a database to store the photographs.
MongoDB operates on Port 27017 by default. You can specify any name for the database in DB_NAME .
The GridFS library stores the photos in the MongoDB database in the following phase.
The preceding code shows how to save photos in a MongoDB database using Python.
How to upload/store images in MongoDB using Node.js, Express & Multer
In this tutorial, I will show you how to upload/store images in MongoDB using Node.js & Express with the help of multer & multer-gridfs-storage.
Overview
Our Node.js Application will provide APIs for:
- uploading Files/Images to MongoDB
- getting list of Files’ information (file name & url)
- downloading File/Image from server with the url

You can use an HTTP Client for image upload:

The images will be stored in 2 collections: photo.files and photos.chunks .


If we get list of image files, the Node.js Rest Apis will return:

Each item in the response array has a url that you can use for downloading the file/image.
These are APIs to be exported:
| Methods | Urls | Actions |
|---|---|---|
| POST | /upload | upload a File/Image |
| GET | /files | get List of Images (name & url) |
| GET | /files/[filename] | download a File |
Node.js upload/store image in MongoDB
We’re gonna show you how to build this Node.js app step by step.
Project Structure
Now look at our project structure:

– config/db.js : includes configuration for MongoDB and Multer (url, database, image Bucket).
– views/index.html : contains HTML form for user to upload images.
– routes/index.js : defines routes for endpoints that is called from views, use controllers to handle requests.
– controllers :
- home.js returns views/index.html
- upload.js handles upload, store, display and download images
– middleware/upload.js : initializes Multer GridFs Storage engine (including MongoDB) and defines middleware function.
– server.js : initializes routes, configure CORS, runs Express app.
Setup Node.js modules
Open command prompt, change current directory to the root folder of our project.
Install Express, CORS, Multer, Multer GridFs Storage and MongoDB with the following command:
The package.json file will look like this:
Create View for uploading image
In views folder, create index.html file with the HTML and Javascript code as below:
For HTML part, we create a form with following elements:
- action=»/upload»
- method=»POST»
- enctype=»multipart/form-data»
You also need to notice the input tag with the name=»file» attribute that we will use in the middleware.
The jQuery script shows preview of the chosen images.
We also use Bootstrap to make the UI more comfortable to read.
Configure MongoDB database
config/db.js
Create middleware for uploading & storing image
Inside middleware folder, create upload.js file with the following code:
– We define a storage configuration object with GridFsStorage class.
- url : must be a standard MongoDB connection string pointing to the MongoDB database. multer-gridfs-storage module will create a mongodb connection for you automatically.
- options : customizes how to establish the connection, specified in the MongoClient.connect documentation.
- file : this is the function to control the file storage in the database. The return value of this function is an object with the properties such as: filename , metadata , chunkSize , bucketName , contentType … We also check if the file is an image or not using file.mimetype . Then we add the [timestamp]-bezkoder- prefix to the file’s original name to make sure that the duplicates never occur in MongoDB collection. bucketName indicates that the file will be stored at photos.chunks and photos.files collections.
– Next we use multer module to initialize middleware and util.promisify() to make the exported middleware object can be used with async-await .
– The single() function with the parameter is the name of input tag (in html view: <input type=»file» name=»file»> ) will store the single file in req.file .
If you want to do more, for example, resize the images, please visit this post:
Upload & resize multiple images in Node.js using Express, Multer, Sharp
Create Controller for the view
Create Controller for uploading Images
– For File Upload method, we will export upload() function that:
- use middleware function for file upload
- catch Multer error (in middleware function)
- return response with message
– For Image File Information and Download:
- getListFiles() : read all files in MongoDB collection photos.files , return list of files’ information (name, url)
- download() : receives file name as input parameter, open download Stream from mongodb built-in GridFSBucket , then response.write(chunk) API to transfer the file to the client.
Define routes
In routes folder, define routes in index.js with Express Router.
There are 4 routes:
– GET: Home page for the upload form.
– POST «/upload» to call the uploadFiles function of the controller. This is also for action=»/upload» in the view.
– GET /files for list of Images.
– GET /files/:name to download the image with the file name.
Create Express app server
Finally, we create an Express server.
What we do are:
– import express and cors modules:
- Express is for building the Rest apis provides Express middleware to enable CORS with various options.
– create an Express app, then add cors middlewares using app.use() method. Notice that we set origin: http://localhost:8081 .
– listen on port 8080 for incoming requests.
Run & Check result
On the project root folder, run this command: node src/server.js
The console shows:
Open browser with url http://localhost:8080/ .

Click on Submit button, if the file is uploaded and stored in MongoDB successfully, the console shows image’s information:
Check MongoDB database, you will see bezkoder_files_db with 2 collections: photos.chunks & photo.files :

Node.js upload/store multiple images in MongoDB
Now I will show you how to modify some code to deal with multiple images instead of only one image at a time.
Change form for uploading multiple images
For the form, we write the input tag with new multiple attribute like this.
Modify middleware for uploading & storing image
For multiple images, we use another function: array() instead of single() .
– array() function limits the number of files to upload each time, the first parameter is the name of – input tag (in html view: <input type=»file» name=»file»> ), the second parameter is the max number of files ( 10 ).
Controller for uploading multiple images
With the controller, we update the uploadFiles function.
There is a additional part in the catch() block. We check if the error.code is «LIMIT_UNEXPECTED_FILE» for showing user the message when he tries to upload more than 10 images/files.
Don’t forget to change the controller method on router:
Run & Check result
Run the command: node src/server.js
And the console shows:
Open your browser with url http://localhost:8080/ , add some images like this:

Click on Submit button. If these images are uploaded and stored in MongoDB successfully, you can see:

The console shows these images’ information:
Check MongoDB database:
— photos.files collection:


If you try to upload more than 10 files at a time, you can see the error like this:

Conclusion
Today we’ve learned how to upload and store single/multiple images in MongoDB database using express, multer & multer-gridfs-storage modules, way to limit the number of files by configuration.
We also know how to get list of uploaded files/images, and provide urls for download.
Happy learning! See you again.
Further Reading
Node.js & MongoDB Associations:
Fullstack CRUD App:
Source Code
You can find the complete source code for this tutorial at Github.
34 thoughts to “How to upload/store images in MongoDB using Node.js, Express & Multer”
How would we display the image from the database?
How can i submit other details such as name , time , price of a product(for example) along with the image??
Any help would be appreciated
Hello Sir,I am getting this Error: The database connection must be open to store files I have clone your code but still I am getting this error ,please help sir how can I solve this?
Hi, you need to run MongoDB first.
In Middleware/upload.js
const
instead
const GridFsStorage = require(“multer-gridfs-storage”);
Does it work if I want to upload videos instead of images?
Hi,
Thanks for your post.
Can you help me config connect to mongoose online before upload the image?
This is just excelent. Thanks
Thanks a ton bezkoder, super useful for my little app!
Would it by any chance be possible to show us how to build a ‘get’ request and display on the webpage as well?
where the uploaded file is located? directory …
What of I i want to use diskStorage and then save the url to mongodb can you please do a tutorial on that.. Or how do I do it
Hello Bezkoder and many thanks for your tut.
There is nothing more wonderful than if you could guide to read uploaded image and especially with image have many chunks(n: 0, n: 1, n:2). Big thanks
I’m also getting an “unexpected field” error when I try to upload an image in post man. Help?
I’m getting an error saying there is no such file or directory (can’t find my index.html file when I run the server).
Help?
how to read uploaded photo from mongodb?
Thank you for your effort! This is really helpfull.
I’m trying to upload 2 images at once, and I need then to be nested in one single document. It should look like this:
> <
_id “xxxxx”,
name: “xxxxxx”,
age: “XX”,
img1: FIRST_IMAGE_ID (probably a document),
img2: SECOND_IMAGE_ID (probably a document)
>
Is that possible?
Firstly, the information provided was really awesome!
A question: Can we follow the same procedure If in case we have multiple inputs types like username, address along with image attachment? If there is any other way around please suggest.
Store images in a MongoDB database
How can I store images in a MongoDB database rather than just text? Can I create an array of images in a MongoDB database? Will it be possible to do the same for videos?
![]()
8 Answers 8
Please see the GridFS docs for details on storing such binary data.
Support for your specific language should be linked to at the bottom of the screen.
![]()
«You should always use GridFS for storing files larger than 16MB» — When should I use GridFS?
MongoDB BSON documents are capped at 16 MB. So if the total size of your array of files is less than that, you may store them directly in your document using the BinData data type.
Videos, images, PDFs, spreadsheets, etc. — it doesn’t matter, they are all treated the same. It’s up to your application to return an appropriate content type header to display them.
How to store images on MongoDB
Images have become a crucial part of the internet. It’s not just web applications that need images, social media has made sure that users not only consume data but also produce and share them. Applications like WhatsApp, Telegram, and Discord also support sharing documents. So, as a backend developer, handling images and storing them on the database is a must. For this tutorial, I am assuming that you are fairly good with ExpressJS and can use Mongoose, or at least know how to use the MongoDB native drivers for NodeJS. I am also assuming that your Express Server is already set up with Mongoose, or that you are using the native MongoDB drivers for NodeJS
Form encoding
When making a POST request, you need to encode the data that is passed along to the backed so that it can be easily parsed. HTML forms provide three methods of encoding:
- application/x-www-form-urlencoded: The default mode of encoding. A long string of name-values is created, where each name and value pair is separated by an = , and each pair is separated by an & so that it can be parsed by the server.
- multipart/form-data: This encoding is used when there is a need for files to be uploaded to the server.
- text/plain: They have been introduced as a part of the HTML 5 specification, and are not used widely in general.
Why image handling is different on Express?
When you send form data to the express backend, express is equipped with handling the application/x-www-form-urlencoded and the text/plain encodings, it cannot process the multipart/form-data encoding, which is primarily used for uploading files. This is where Multer comes in. A node.js middleware that will handle multipart encoded forms for us.
Setting up your Schema
You need to define a schema Upload.js for the collection where you are going to store your images. If you are using the native MongoDB drivers, you can skip this part.
In the above schema, the file block is the most important one, the rest can be conveniently ignored to match your requirements.
Setting up multer
Install Multer for your application:
Using npm:
Using yarn:
yarn add multer
Now, let’s create a route that will handle file upload. But before that, let’s enable our app to use multer in upload.js .
This snippet makes sure that the file is parsed and stored in the memory. WARNING: Make sure that you take steps to make sure that the file being uploaded isn’t huge, or else you could be looking at a Denial-of-service threat. There are some options that you can use in multer. Take a look at them here.
Using multer middleware in your route
Now that you have set up multer successfully, it is time to use it as a middleware in your requests.
You can also use upload.array() instead of upload.single() if you are expecting to receive more than one file from the frontend. More about that here.
Code explanation
The middleware upload.single("image") is used to tell the server that only one file is being expected from the browser. The argument inside the upload.single() tells the name of the file field in the HTML form. Using this middleware enables us to use req.file inside the route definition to access the received file. We used req.file.buffer and req.file.mimetype to save the file on the database. The buffer is raw binary data of the file received and we'll store it on the database as it is. The req.file.mimetype is also very important for us as it'll tell the browser how to parse the raw binary data, i.e. what to interpret the data as, whether it be a png image or jpeg, or something else. To find out what other information can be accessed from req.file , click here. We had to break the file object into two properties, namely data, which contains the raw binary, and the contentType, which contains the mimetype.
Sending data from Frontend
Remember, multer only accepts multipart/form-data for files. That is why we need to set the encoding type to the same on our frontend.
How to convert it back to an image?
Well, there are basically two ways you can do this. You either convert the binary data to the image on the backend and then send it to the frontend, or you send the binary data to the frontend and then convert it to an image. It totally depends on your liking and your use case. How to do it? Well, that article is for another WebDev Monday.