maria
maria

Reputation: 159

Mongodb duplicate key error collection dup key: null

Im trying to create multiple accounts.

The first account always works, but when im trying to make a new one i get the following error:

BulkWriteError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: db.users.$friends.userid_1  dup key: { : null }

The first user is fine, containing friends with an empty array, as i would like it to be.

But the next user is not created.

What do i have to do to fix this error?

The user schema piece of friends in users is the following:

   friends : [
    {
        userid : {type: String, default: '', unique: true },
    }
],
friendRequests: [
    {
        userid : {type: String, default: '', unique: true },
    }

EDIT:

i have been looking into https://docs.mongodb.com/manual/core/index-unique/#unique-index-and-missing-field but still couldnt make it work.

EDIT2:

By default, its not creating any friends or friendrequests.

EDIT3:

full code:

passport.use('local-signup', new LocalStrategy({
            usernameField : 'username',
            passwordField : 'password',
            passReqToCallback : true,
        },
        function(req, username, password, done) {
            process.nextTick(function() {
                console.log("doing local signup");
                username = username.toLowerCase();
                Account.findOne({username :  username }, function(err, user) {
                    var expr = "/admin/";
                    if (err) {
                        return done(err);
                    } else if (user) {
                        return done(null, false, 'That username is already taken.');
                    } else if(username.length < 3 || username.length >= 12) {
                        return done(null, false, 'Username has to be between 3 and 12 characters! :( '  + username);
                    } else if(/^[a-zA-Z0-9- ]*$/.test(username) == false) {
                        return done(null, false, 'You cant have any special characters!');
                    } else if(password.length < 5 || password.length > 15) {
                        return done(null, false, 'Password need to be 5-15 characters long!');
                    } else {

                        var newUser            = new Account();
                        newUser.username    = username;
                        newUser.password = newUser.encryptPassword(password);
                        newUser.save(function(err) {
                            if (err)
                                throw err;
                            return done(null, newUser);
                        });
                    }
                });

            });

        }));

user model:

var mongoose     = require('mongoose');
var Schema       = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var bcrypt   = require('bcrypt-nodejs');



var UserSchema   = new Schema({
    username: {type: String, index: { unique: true }},
    password: {type: String},
    salt: { type: String},
    hash: {type: String},
    gender : {type: String, default: 'male'},
    friends : [
        {
            userid : {type: String, default: '', unique: true },
        }
    ],
    friendRequests: [
        {
            userid : {type: String, default: '', unique: true },
        }
    ]

});
UserSchema.methods.encryptPassword = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(10));
}

UserSchema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.password);
}



module.exports = mongoose.model('Users', UserSchema);

Upvotes: 3

Views: 2712

Answers (1)

s7vr
s7vr

Reputation: 75994

As noted in the comment Mongodb doesn't enforce uniqueness in array values inside single document.

So you have to handle the uniqueness in array inside the client code. You can use combination of strategy to handle the requirement for you.

First remove the unique index and use Mongoose unique array plugin to have mongoose check the uniqueness in the array when you create/update a document.

The plugin works for both scalar and document arrays.For your case you can do the following changes.

var uniqueArrayPlugin = require('mongoose-unique-array');
UserSchema.plugin(uniqueArrayPlugin);

This will enforce the validation through validator and should show you an validation message when you perform update/save operation.

As noted in the blog the unique plugin doesn't work when you use $push in update query.

You can use

Account.findOne({"friends.userid":{"$ne":inputuserid}}, {"$push":{"friends":new user doc}});

Read blog and usage examples from author for more information.

Upvotes: 1

Related Questions