How to save an image in my obkect?

This is my object. How I can insert an image to the database in “image” field.

class Product : EmbeddedRealmObject {
    var name: String = ""
    var category: String = ""
    var description: String? = ""
    var price: Float = 0F
    var imagine: String? = null
}

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.

But if you must store BLOBs in MongoDB, use GridFS

1 Like

How other users can see the image if its stored on my file system? How I could upload the image?

I’m assuming this is a web application. When the user requests the image, load it via your web application. I do this in PHP + Apache all the time.

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:

  1. 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.

  2. 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

See this article for more details: Realm Data and Partitioning Strategy Behind the WildAid O-FISH Mobile Apps | MongoDB

1 Like

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?

  • upload images to a storage provider.
  • 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.

2 Likes

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.

1 Like