To create a unique index, use the db. collection. createIndex() method with the unique option set to true .
The unique option tells Mongoose that each document must have a unique value for a given path. For example, below is how you can tell Mongoose that a user's email must be unique. const mongoose = require('mongoose'); const userSchema = new mongoose.
Right-click the table on which you want to create a unique index and select Design. On the Table Designer menu, select Indexes/Keys. In the Indexes/Keys dialog box, click Add. Select the new index in the Selected Primary/Unique Key or Index text box.
mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema. This makes error handling much easier, since you will get a Mongoose validation error when you attempt to violate a unique constraint, rather than an E11000 error from MongoDB.
Oops! You just have to restart mongo.
Oops! You just have to restart mongo.
And re-index too, with:
mongo <db-name>
> db.<collection-name>.reIndex()
In testing, since I don't have important data, you can also do:
mongo <db-name>
> db.dropDatabase()
I ran into the same issue: I added the unique constraint for the email
field to our UserSchema
after already having added users to the db, and was still able to save users with dupe emails. I resolved this by doing the following:
1) Remove all documents from the users collection.
2) From the mongo shell, execute the command:
db.users.createIndex({email: 1}, {unique: true})
Regarding step 1, note that from Mongo's docs:
MongoDB cannot create a unique index on the specified index field(s) if the collection already contains data that would violate the unique constraint for the index.
https://docs.mongodb.com/manual/core/index-unique/
I've done something like this:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const FooSchema = new Schema({
name: { type: String, required: true, index: true, unique: true }
});
const Foo = mongoose.model('Foo', FooSchema);
Foo.createIndexes();
module.exports = Foo
I added the Foo.createIndexes()
line b.c. I was getting the following deprecation warning when the code was being ran:
(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
I'm not sure if Foo.createIndexes()
is asynchronous, but AFAIK things seem to be working fine
This behavior happen also if you have left some duplicates in Mongo. Mongoose will try to create them in Mongo when your application starts up.
To prevent this, you can handle this error this way :
yourModel.on('index', function(err) {
if (err?) {
console.error(err)
}
);
Ok, i was able to resolve this from the mongoshell by adding the index on the field and setting the unique property:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell should respond in this way:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
Now to test quickly from the mongoshell:
var doc = {fieldName: 'abc'};
db.<collectionName>.insert(doc)
Should give: WriteResult({ "nInserted" : 1 })
But when repeating again:
db.<collectionName>.insert(doc)
Will give:
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1 dup key: { : \"[email protected]\" }"
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With