Don’t. Put the image in the file system and put its path into the db.
MongoDB does not excel at storing BLOBs or CLOBs. It’s better just to point to them.
I agree with @Jack_Woehr here. Storing images in a database is not only an anti-pattern, but also it is not cost-effective. Generally images should be stored in cheaper cold-storage like S3.
That being said, our customers generally go one of 2 routes:
If the images are small and you can guarantee that, put them in your documents. Its not the most scalable approach, but in some cases it is fine and the simplest approach.
Two-Phase Upload. Add a new object type called Images that is a separate non-embedded object. When you need to upload an image for a product, insert a new “image object” with the binary data along with a link or reference to the product it represents (the _id perhaps). Then, you can have a Database Trigger listen to the “images” collection for insert events and do the following:
1. Take the image in the binary, upload it to S3
2. Delete the image document from MongoDB
3. Set the image_url field in the corresponding product document to the new S3 image
Thanks for the answer. I am developing a mobile application. The images will just be about food. What is the best approach to store them so the users can see them?
get the URL of that file from the storage provider
embed this URL to your document
use the URL from your document in an IMG tag in your HTML.
for pretty small size images, you may
directly encode them with BASE64
prepend data tag to it data:image/png;base64, (change image type) and store it in your document.
use it in IMG tag in your HTML
this second method can fill up your database quickly if your app is not implemented correctly, or the number of files goes out of hand. you would not want a million files of size 100KB.
We had a talk and you selected to go with saving images into the database. here are a few things to note:
embedding is acceptable if it will be a single image. yet, your document will be fat and your read operation will be slow for a given document.
if a product has multiple images, best option is to keep them in an array (fat document) but adding more images to the array will affect performance.
creating an image collection is another option.
first create a product document with the image field being null, insert it into products collection and get its _id
insert images (note the plural) into images collection, preferably with reference to the product, and get their _id
update the product’s image reference.
this second option will make two trips to query the database, but will separate two an important logic problem. also add possibility to independently process images.
you may also extend this and have 2 API endpoints, one to process product details and the other for images. this may complicate the app a bit, but will have more pros than cons I believe.
One last thing about your mobile app. Mobile data is something precious. So if you can move your image reshape/encode to it, even if it might be slow when processing the uploads and they may not consciously notice, your users will appreciate it for the use of internet bandwidth.