mongoose独特的索引不工作!
我试图让MongoDB检测基于其索引的重复值。 我认为这在MongoDB中是可能的,但是通过Mongoose包装,事情似乎被破坏了。 所以对于这样的事情:
User = new Schema ({ email: {type: String, index: {unique: true, dropDups: true}} }) 我可以用相同的电子邮件保存2个用户。 该死。
同样的问题已经expression在这里: https : //github.com/LearnBoost/mongoose/issues/56 ,但那个线程是老的,并导致无处。
现在,我正在手动调用数据库来查找用户。 由于“电子邮件”被索引,该呼叫并不昂贵。 但是让它在本地处理还是很好的。
有没有人有这个解决scheme?
哎呀! 你只需要重新启动mongo。
哎呀! 你只需要重新启动mongo。
而且重新索引呢!
在testing中,我只是做了一个:
 mongo <db-name> > db.dropDatabase() 
虽然如果你有重要的数据,你可能只需要:
 mongo <db-name> > db.<collection-name>.reIndex() 
如果您在Mongo中留下了一些重复项,也会发生这种情况。 当您的应用程序启动时,Mongoose将尝试在Mongo中创build它们。
为了防止这种情况,你可以这样处理这个错误:
 yourModel.on('index', function(err) { if (err?) { console.error err } ); 
 我遇到了同样的问题:我已经添加了用户到数据库后,我们添加了唯一的email字段限制到我们的UserSchema ,并仍然能够保存用户与愚蠢的电子邮件。 我通过下列方式解决了这个问题: 
1)删除用户集合中的所有文档。
  2)从mongo shell执行命令: db.users.createIndex({email: 1}, {unique: true}) 
关于第1步,请注意,从Mongo的文档:
如果集合已经包含违反索引唯一约束的数据,则MongoDB不能在指定的索引字段上创build唯一索引。
好吧,我可以通过在字段中添加索引并设置唯一属性来解决这个问题。
 db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true}); 
壳牌应该这样回应:
 { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } 
现在从mongoshell快速testing:
 var doc = {fieldName: 'abc'}; db.<collectionName>.insert(doc) 
应该给:WriteResult({“nInserted”:1})
但是当再次重复:
 db.<collectionName>.insert(doc) 
会给:
 WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1 dup key: { : \"martyna@martycud.com\" }" } }) 
根据文档: https : //docs.mongodb.com/v2.6/tutorial/modify-an-index/
要修改现有的索引,您需要删除并重新创build索引。
不要重新启动MONGO!
1 – 删除collections
 db.users.drop() 
2 – 重新索引表格
 db.users.ensureIndex({email: 1, type: 1}, {unique: true}) 
您也可以通过删除索引来解决此问题;
 假设您想要从集合users和字段username删除唯一索引,请键入以下内容: 
 db.users.dropIndex('username_1'); 
如果表/集合为空,则为该字段创build唯一索引:
 db.<collection_name>.createIndex({'field':1}, {unique: true}) 
如果表/集合不是空的,则删除集合并创build索引:
 db.<collection_name>.drop() db.<collection_name>.createIndex({'field':1}, {unique: true}) 
现在重新启动mongoDB。
mongoose唯一的validation器
如何使用这个插件:
1)npm install –save mongoose-unique-validator
2)在你的模式中遵循本指南:
 // declare this at the top var mongoose = require('mongoose'); var uniqueValidator = require('mongoose-unique-validator'); // exampleSchema = mongoose.Schema({}) etc... exampleSchema.plugin(uniqueValidator); // module.exports = mongoose.model(...) etc.... 
3)mongoose方法
 当使用像findOneAndUpdate这样的方法时,你需要传递这个configuration对象: 
 { runValidators: true, context: 'query' } 
 ie. User.findOneAndUpdate( { email: 'old-email@example.com' }, { email: 'new-email@example.com' }, { runValidators: true, context: 'query' }, function(err) { // ... } 
4)附加选项
- 
不区分大小写 在架构中使用uniqueCaseInsensitive选项 ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }
- 
自定义错误消息 ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });
现在,您可以添加/删除独特的属性到您的模式,而不用担心重新启动mongo,删除数据库或创build索引。
注意事项(来自文档):
由于我们依赖asynchronous操作来validation数据库中是否存在文档,因此可以同时执行两个查询,都返回0,然后都插入到MongoDB中。
在自动locking集合或强制单个连接之外,没有真正的解决scheme。
对于我们的大多数用户来说,这不会是一个问题,但是需要注意的是一个边缘案例。
最新回答:根本不需要重新启动mongodb,如果集群已经有了相同的名字索引,mongoose不会再重新创build索引,那么首先删除集群现有的索引,现在当你运行mongoose时,会创build新的索引上面的stream程解决了我的问题。