Reputation: 4139
Mongoose Model.save is taking over ~1.5+ seconds to complete, and if I user Model.collection.insert method instead its only ~50ms
The second solution unless I'm mistaken is only quicker because its using the native mongoDb driver. I have tried using console.time to isolate where the delay is and its happening just before the Model.prototype.save function is called which is really strange.
The auth.username is indexed so that shouldn't cause the slowness.
Below is an example of the model schema and how i am invoking a new model.
I am using 3.20.0 of mongoose, and 2.6.4 of mongoDB.
var userSchema = new Schema({
active: { type: Boolean, default: true },
player_id: ObjectId,
player: mongoose.Schema.Types.Mixed,
auth: {
token: { type: String, required: true, default: 'temp' },
username: { type: String, required: true, trim: true, lowercase: true, index: { unique: true } },
password: { type: String, required: true },
login_attempts: { type: Number, required: true, default: 0 },
locked_until: { type: Number } ,
},
contact: {
first_name: String,
last_name: String,
nick_name: String,
email: { type: String, required: true, trim: true, lowercase: true, index: { unique: true } },
phone: { type: String, required: false, trim: true, index: { unique: true, sparse: true } }
},
},{collection: 'user' });
-v-v-v-v-v-v-v-v-v-v-v-v-
var mongoose = require('mongoose'),
User = mongoose.model('User');
var newUser = new User(data);
newUser.save(function (err) {
if(err) { return cb(err); }
// Call takes ~1.5+ seconds
});
User.collection.insert(data, function(err, user){
if(err) { return cb(err); }
// Call takes ~50ms
});
Upvotes: 1
Views: 2625
Reputation: 4139
The cause was a 'presave' call and setting the salt factor to high:
userSchema.pre('save', function(next) {
// only hash the password if it has been modified (or is new)
if (!this.isModified('auth.password')) return next();
var user = this;
// generate a salt
bcrypt.genSalt(14 /*<< Setting to 14 from 10 caused call to be 10x slower */, function(err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.auth.password, salt, function (err, hash) {
if (err) return next(err);
// set the hashed password back on our user document
user.auth.password = hash;
next();
});
});
});
Upvotes: 4