E11000 duplicate key error index in mongodb mongoo

2018-12-31 22:04发布

问题:

Following is my user schema in user.js model -

var userSchema = new mongoose.Schema({
    local: {
        name: { type: String },
        email : { type: String, require: true, unique: true },
        password: { type: String, require:true },
    },
    facebook: {
        id           : { type: String },
        token        : { type: String },
        email        : { type: String },
        name         : { type: String }
    }
});

var User = mongoose.model(\'User\',userSchema);

module.exports = User;

This is how I am using it in my controller -

var user = require(\'./../models/user.js\');

This is how I am saving it in the db -

user({\'local.email\' : req.body.email, \'local.password\' : req.body.password}).save(function(err, result){
    if(err)
        res.send(err);
    else {
        console.log(result);
        req.session.user = result;
        res.send({\"code\":200,\"message\":\"Record inserted successfully\"});
    }
});

Error -

{\"name\":\"MongoError\",\"code\":11000,\"err\":\"insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.users.$email_1  dup key: { : null }\"} 

I checked the db collection and no such duplicate entry exists, let me know what I am doing wrong ?

FYI - req.body.email and req.body.password are fetching values.

I also checked this post but no help STACK LINK

If I removed completely then it inserts the document, otherwise it throws error \"Duplicate\" error even I have an entry in the local.email

回答1:

The error message is saying that there\'s already a record with null as the email. In other words, you already have a user without an email address.

The relevant documentation for this:

If a document does not have a value for the indexed field in a unique index, the index will store a null value for this document. Because of the unique constraint, MongoDB will only permit one document that lacks the indexed field. If there is more than one document without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error.

You can combine the unique constraint with the sparse index to filter these null values from the unique index and avoid the error.

unique indexes

Sparse indexes only contain entries for documents that have the indexed field, even if the index field contains a null value.

In other words, a sparse index is ok with multiple documents all having null values.

sparse indexes


From comments:

Your error says that the key is named mydb.users.$email_1 which makes me suspect that you have an index on both users.email and users.local.email (The former being old and unused at the moment). Removing a field from a Mongoose model doesn\'t affect the database. Check with mydb.users.getIndexes() if this is the case and manually remove the unwanted index with mydb.users.dropIndex(<name>).



回答2:

If you are still in your development environment, I would drop the entire db and start over with your new schema.

From the command line

➜ mongo
use dbName;
db.dropDatabase();
exit


回答3:

Check collection indexes.

I had that issue due to outdated indexes in collection for fields, which should be stored by different new path.

Mongoose adds index, when you specify field as unique.



回答4:

This happens when there are frequent schema indexes and changes in a current database and this can be easily fixed by deleting the system indexes and the whole collection.

It Works after doing that, this also happens when there\'s no unique key to separate two documents from each other.

If you\'re using a shell, then you can drop the db via -

db.users.drop();

I Hope this helped :)



回答5:

I faced similar issues , I Just clear the Indexes of particular fields then its works for me . https://docs.mongodb.com/v3.2/reference/method/db.collection.dropIndexes/



回答6:

I want to explain the answer/solution to this like I am explaining to a 5-year-old , so everyone can understand .

I have an app.I want people to register with their email,password and phone number . In my MongoDB database , I want to identify people uniquely based on both their phone numbers and email - so this means that both the phone number and the email must be unique for every person.

However , there is a problem : I have realized that everyone has a phonenumber but not everyone has an email address .

Those that don`t have an email address have promised me that they will have an email address by next week. But I want them registered anyway - so I tell them to proceed registering their phonenumbers as they leave the email-input-field empty .

They do so .

My database NEEDS an unique email address field - but I have a lot of people with \'null\' as their email address . So I go to my code and tell my database schema to allow empty/null email address fields which I will later fill in with email unique addresses when the people who promised to add their emails to their profiles next week .

So its now a win-win for everyone (but you ;-] ): the people register, I am happy to have their data ...and my database is happy because it is being used nicely ...but what about you ? I am yet to give you the code that made the schema .

Here is the code : NOTE : The sparse property in email , is what tells my database to allow null values which will later be filled with unique values .

var userSchema = new mongoose.Schema({
  local: {
    name: { type: String },
    email : { type: String, require: true, index:true, unique:true,sparse:true},
    password: { type: String, require:true },
  },
  facebook: {
    id           : { type: String },
    token        : { type: String },
    email        : { type: String },
    name         : { type: String }
  }
});

var User = mongoose.model(\'User\',userSchema);

module.exports = User;

I hope I have explained it nicely . Happy NodeJS coding / hacking!



回答7:

This is my relavant experience:

In \'User\' schema, I set \'name\' as unique key and then ran some execution, which I think had set up the database structure.

Then I changed the unique key as \'username\', and no longer passed \'name\' value when I saved data to database. So the mongodb may automatically set the \'name\' value of new record as null which is duplicate key. I tried the set \'name\' key as not unique key {name: {unique: false, type: String}} in \'User\' schema in order to override original setting. However, it did not work.

At last, I made my own solution:

Just set a random key value that will not likely be duplicate to \'name\' key when you save your data record. Simply Math method \'\' + Math.random() + Math.random() makes a random string.



回答8:

This is because there is already a collection with the same name with configuration..Just remove the collection from your mongodb through mongo shell and try again.

db.collectionName.remove()

now run your application it should work



回答9:

I had the same issue. Tried debugging different ways couldn\'t figure out. I tried dropping the collection and it worked fine after that. Although this is not a good solution if your collection has many documents. But if you are in the early state of development try dropping the collection.

db.users.drop();


回答10:

I had a similar problem and I realized that by default mongo only supports one schema per collection. Either store your new schema in a different collection or delete the existing documents with the incompatible schema within the your current collection. Or find a way to have more than one schema per collection.



回答11:

I got this same issue when I had the following configuration in my config/models.js

module.exports.models = {
  connection: \'mongodb\',
  migrate: \'alter\'
}

Changing migrate from \'alter\' to \'safe\' fixed it for me.

module.exports.models = {
  connection: \'mongodb\',
  migrate: \'safe\'
}


回答12:

same issue after removing properties from a schema after first building some indexes on saving. removing property from schema leads to an null value for a non existing property, that still had an index. dropping index or starting with a new collection from scratch helps here.

note: the error message will lead you in that case. it has a path, that does not exist anymore. im my case the old path was ...$uuid_1 (this is an index!), but the new one is ....*priv.uuid_1



回答13:

I had the same issue when i tried to modify the schema defined using mangoose. I think the issue is due to the reason that there are some underlying process done when creating a collection like describing the indices which are hidden from the user(at least in my case).So the best solution i found was to drop the entire collection and start again.



回答14:

I had same Issue. Problem was that I have removed one field from model. When I dropped db it fixes



回答15:

Change the collection name if it already exists in the database, it will show an error. And if you given any property as unique the same error will occur.



回答16:

Had the same issue I resolved it by removing the unique attribute on the property.

Just find another way to validate or check for unique property values for your schema.



回答17:

Please clear the collection or Delete the entire collection from MongoDB database and try again later.