_id With Mongoose
Let us take a very common use-case: “There will be a registration page for users, where users will provide their required details along with their picture”.
Details would be saved to MongoDB while the pictures would be uploaded to Cloudinary or S3 with user unique id.”
Suppose we have User Schema as given below:
[js]
/*
* Schema Defined with Mongoose.
* */
var UserSchema = mongoose.Schema({
name: {type: String, required: true},
age: {type: Number, min: 16, max: 60, required: true},
password: {type: String, required: true},
});
var User = mongoose.model(‘User’, UserSchema);
[/js]
We have custom fileManager module to upload image on Cloudinary/S3, we requiring as below:
[js]
/*
* file Manager custome Module to upload image to Cloudinary/S3
* */
var fileManager = require("Cloudinary/S3 File Manager");
[/js]
Now suppose user provided the following details at the time registration:
[js]
/*
* Details provided by user
* */
var userDetails = {
name: "Amit Thakkar",
age: 25,
password: "igblog",
image: "imagePath"
};
[/js]
To achieve this use-case, let us discuss the approach we were following earlier. As we are familiar with _id field, which MongoDB auto generates for every document in case it is not provided at the time of saving/inserting, and is unique for the whole collection. So first we saved user details to MongoDB, then we got unique _id field (which is auto generated by MongoDB) for that user, and then only we uploaded user image to Cloudinary/S3 with that _id. 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 MongoDB and then sent error message in response. Let’s see this with the help of code:
[js]
/*
* What we were doing earlier
* */
new User(userDetails).save(function (error, user) {
if (error) {
// Return Error Message
} else {
// Uploading Image to Cloudinary/S3
var options = {
publicId: user._id,
path: userDetails.image
};
fileManager.uploadImage(options, function (error, result) {
if (error) {
User.remove({_id: user._id}, function (error, removed) {
if(error) {
// log ERROR
}
});
// Return ERROR Message
} else {
// Return SUCCESS Message
}
});
}
});
[/js]
Earlier if any error occurred at the time of uploading image to Cloudinary/S3, we used to hit two queries to MongoDB (first one for inserting/saving the user details and second one for removing the userdetails). In order to avoid these two MongoDB queries, we are now using _id field generated By Mongoose. Mongoose provides us an _id field to read before saving the document (user details) to MongoDB. When we do new User(userDetails), then Mongoose returns user(new Model Object of User) with _id field. We use that _id field for uploading image to Cloudinary/S3, and if image is uploaded successfully then only we save user details to MongoDB, otherwise return ERROR.
[js]
/*
* New approach
* */
var user = new User(userDetails);
var options = {
publicId: user._id,
path: userDetails.image
};
// Uploading Image to Cloudinary/S3
fileManager.uploadImage(options, function (error, result) {
if (error) {
// Return ERROR Message
} else {
user.save(function (error, user) {
if (error) {
// Return Error Message
} else {
// Return SUCCESS Message
}
});
}
});
[/js]
So with the second way, we can write more clean and optimized code.
NOTE: When we are saving document via mongoose. _id field is auto generated by Mongoose and gets attached to the Model, and at the time of saving/inserting the document into MongoDB, MongoDB will use that unique _id field which was generated by Mongoose.
Amit Kumar
amit.kumar@intelligrape.com
in.linkedin.com/in/amitkumar0110
twitter.com/amit_kumar0110
More Blogs by Me
the schema has no mention about the image field but the userdetail document has image . so wouldn’t that be an issue . Also how could i get image in android and upload it via this method. Plzz i would appreciate a little help.!!