{"id":12944,"date":"2014-04-12T23:30:23","date_gmt":"2014-04-12T18:00:23","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=12944"},"modified":"2016-12-19T15:31:08","modified_gmt":"2016-12-19T10:01:08","slug":"_id-with-mongoose","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/_id-with-mongoose\/","title":{"rendered":"_id With Mongoose"},"content":{"rendered":"<p>Let us take a very common use-case: &#8220;<strong>There will be a registration page for users, where users will provide their required details along with their picture<\/strong>\u201d.<\/p>\n<p>Details would be saved to <strong>MongoDB<\/strong> while the pictures would be uploaded to <strong>Cloudinary or S3<\/strong> with user unique <strong>id<\/strong>.&#8221;<br \/>\nSuppose we have <strong>User<\/strong> <strong>Schema<\/strong> as given below:<br \/>\n[js]<br \/>\n\/*<br \/>\n * Schema Defined with Mongoose.<br \/>\n * *\/<br \/>\nvar UserSchema = mongoose.Schema({<br \/>\n    name: {type: String, required: true},<br \/>\n    age: {type: Number, min: 16, max: 60, required: true},<br \/>\n    password: {type: String, required: true},<br \/>\n});<br \/>\nvar User = mongoose.model(&#8216;User&#8217;, UserSchema);<br \/>\n[\/js]<br \/>\nWe have custom fileManager module to upload image on Cloudinary\/S3, we requiring as below:<br \/>\n[js]<br \/>\n\/*<br \/>\n * file Manager custome Module to upload image to Cloudinary\/S3<br \/>\n * *\/<br \/>\nvar fileManager = require(&quot;Cloudinary\/S3 File Manager&quot;);<br \/>\n[\/js]<br \/>\nNow suppose user provided the following details at the time registration:<br \/>\n[js]<br \/>\n\/*<br \/>\n * Details provided by user<br \/>\n * *\/<br \/>\nvar userDetails = {<br \/>\n    name: &quot;Amit Thakkar&quot;,<br \/>\n    age: 25,<br \/>\n    password: &quot;igblog&quot;,<br \/>\n    image: &quot;imagePath&quot;<br \/>\n};<br \/>\n[\/js]<br \/>\nTo achieve this use-case, let us discuss the approach we were following earlier. As we are familiar with <strong>_id<\/strong> field, which <strong>MongoDB<\/strong> auto generates for every document in case it is not provided at the time of saving\/inserting, and is <strong>unique<\/strong> for the whole <strong>collection<\/strong>. So first we saved user details to <strong>MongoDB<\/strong>, then we got <strong>unique<\/strong> <strong>_id<\/strong> field (which is <strong>auto generated<\/strong> by <strong>MongoDB<\/strong>) for that user, and then only we uploaded user image to Cloudinary\/S3 with that <strong>_id<\/strong>. If at the time of uploading the image to Cloudinary\/S3, any error occurred (because of any reason), then we removed the saved user details from <strong>MongoDB<\/strong> and then sent error message in response. Let\u2019s see this with the help of code:<br \/>\n[js]<br \/>\n\/*<br \/>\n * What we were doing earlier<br \/>\n * *\/<br \/>\nnew User(userDetails).save(function (error, user) {<br \/>\n    if (error) {<br \/>\n        \/\/ Return Error Message<br \/>\n    } else {<br \/>\n        \/\/ Uploading Image to Cloudinary\/S3<br \/>\n        var options = {<br \/>\n            publicId: user._id,<br \/>\n            path: userDetails.image<br \/>\n        };<br \/>\n        fileManager.uploadImage(options, function (error, result) {<br \/>\n            if (error) {<br \/>\n                User.remove({_id: user._id}, function (error, removed) {<br \/>\n                    if(error) {<br \/>\n                        \/\/ log ERROR<br \/>\n                    }<br \/>\n                });<br \/>\n                \/\/ Return ERROR Message<br \/>\n            } else {<br \/>\n                \/\/ Return SUCCESS Message<br \/>\n            }<br \/>\n        });<br \/>\n    }<br \/>\n});<br \/>\n[\/js]<br \/>\nEarlier if any error occurred at the time of uploading image to Cloudinary\/S3, we used to hit two queries to <strong>MongoDB<\/strong> (first one for inserting\/saving the user details and second one for removing the userdetails). In order to avoid these two <strong>MongoDB<\/strong> queries, we are now using <strong>_id<\/strong> field generated By <strong>Mongoose<\/strong>. <strong>Mongoose<\/strong> provides us an <strong>_id<\/strong> field to read before saving the document (user details) to <strong>MongoDB<\/strong>. When we do new User(userDetails), then <strong>Mongoose<\/strong> returns user(new Model Object of User) with <strong>_id<\/strong> field. We use that <strong>_id<\/strong> field for uploading image to Cloudinary\/S3, and if image is uploaded successfully then only we save user details to <strong>MongoDB<\/strong>, otherwise return ERROR.<br \/>\n[js]<br \/>\n\/*<br \/>\n * New approach<br \/>\n * *\/<br \/>\nvar user = new User(userDetails);<br \/>\nvar options = {<br \/>\n    publicId: user._id,<br \/>\n    path: userDetails.image<br \/>\n};<br \/>\n\/\/ Uploading Image to Cloudinary\/S3<br \/>\nfileManager.uploadImage(options, function (error, result) {<br \/>\n    if (error) {<br \/>\n        \/\/ Return ERROR Message<br \/>\n    } else {<br \/>\n        user.save(function (error, user) {<br \/>\n            if (error) {<br \/>\n                \/\/ Return Error Message<br \/>\n            } else {<br \/>\n                \/\/ Return SUCCESS Message<br \/>\n            }<br \/>\n        });<br \/>\n    }<br \/>\n});<br \/>\n[\/js]<br \/>\nSo with the second way, we can write more clean and optimized code.<\/p>\n<p><strong>NOTE:<\/strong> When we are saving document via <strong>mongoose<\/strong>. <strong>_id<\/strong> field is auto generated by <strong>Mongoose<\/strong> and gets attached to the <strong>Model<\/strong>, and at the time of saving\/inserting the document into <strong>MongoDB<\/strong>, <strong>MongoDB<\/strong> will use that <strong>unique<\/strong> <strong>_id<\/strong> field which was generated by <strong>Mongoose<\/strong>.<\/p>\n<p>Amit Kumar<br \/>\n<a href=\"http:\/\/www.tothenew.com\/blog\/author\/amit.kumar\/\">amit.kumar@intelligrape.com<\/a><br \/>\nin.linkedin.com\/in\/amitkumar0110<br \/>\ntwitter.com\/amit_kumar0110<br \/>\n<strong><a href=\"http:\/\/www.tothenew.com\/blog\/author\/amit-kumar\/\">More Blogs by Me<\/a><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let us take a very common use-case: &#8220;There will be a registration page for users, where users will provide their required details along with their picture\u201d. Details would be saved to MongoDB while the pictures would be uploaded to Cloudinary or S3 with user unique id.&#8221; Suppose we have User Schema as given below: [js] [&hellip;]<\/p>\n","protected":false},"author":52,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":4},"categories":[1185],"tags":[1383,4846,1316,1177],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/12944"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/52"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=12944"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/12944\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=12944"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=12944"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=12944"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}