Mongodb Mongoose唯一索引不工作!
我试图让MongoDB根据索引检测重复值。我认为这在MongoDB中是可能的,但是通过Mongoose包装,东西似乎被破坏了。所以对于这样的事情:Mongodb Mongoose唯一索引不工作!,mongodb,node.js,mongoose,Mongodb,Node.js,Mongoose,我试图让MongoDB根据索引检测重复值。我认为这在MongoDB中是可能的,但是通过Mongoose包装,东西似乎被破坏了。所以对于这样的事情: User = new Schema ({ email: {type: String, index: {unique: true, dropDups: true}} }) const mongoose = require('mongoose'); const Schema = mongoose.Schema; const FooSchema =
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
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
我可以用相同的电子邮件保存2个用户。该死
这里也表达了同样的问题:,但这条线索已经过时,没有任何结果
现在,我正在手动调用db以查找用户。这个电话并不昂贵,因为“电子邮件”是有索引的。但是,让它在本地处理还是很好的
有人能解决这个问题吗?哎呀!你只需要重新启动mongo
哎呀!你只需要重新启动mongo 并重新编制索引,包括:
mongo <db-name>
> db.<collection-name>.reIndex()
mongo
>db..reIndex()
在测试中,由于我没有重要数据,您还可以:
mongo <db-name>
> db.dropDatabase()
mongo
>db.dropDatabase()
如果您在Mongo中留下了一些重复项,这种行为也会发生。当应用程序启动时,Mongoose将尝试在Mongo中创建它们
要防止出现这种情况,可以通过以下方式处理此错误:
yourModel.on('index', function(err) {
if (err?) {
console.error(err)
}
);
好的,通过在字段上添加索引并设置unique属性,我可以从mongoshell解决这个问题:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
现在从mongoshell快速测试:
var doc = {fieldName: 'abc'};
db.<collectionName>.insert(doc)
您还可以通过删除索引来解决此问题 假设要从集合
用户
和字段用户名
中删除唯一索引,请键入以下内容:
db.users.dropIndex('username_1');
根据文档:
要修改现有索引,需要删除并重新创建索引
不要重启MONGO
1-删除集合
db.users.drop()
2-重新索引表格
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
我遇到了同样的问题:在已经将用户添加到数据库之后,我将
电子邮件
字段的唯一约束添加到了用户模式
,并且仍然能够使用重复的电子邮件保存用户。我通过以下操作解决了此问题:
1) 从用户集合中删除所有文档
2) 在mongo shell中,执行以下命令:
db.users.createIndex({email:1},{unique:true})
关于步骤1,请注意Mongo的文档:
如果集合已包含违反索引唯一约束的数据,MongoDB无法在指定的索引字段上创建唯一索引
如何使用此插件:
1) npm安装--保存mongoose唯一验证程序
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) 猫鼬方法
使用类似于findOneAndUpdate
的方法时,需要传递此配置对象:
{runValidators:true,上下文:'query'}
ie. User.findOneAndUpdate(
{ email: 'old-email@example.com' },
{ email: 'new-email@example.com' },
{ runValidators: true, context: 'query' },
function(err) {
// ...
}
4) 附加选项
ie.email:{type:String,index:true,unique:true,required:true,uniquecase不敏感:true}
ie.exampleSchema.plugin(uniqueValidator,{message:'Error,预期{PATH}是唯一的。})代码>
对于我们的大多数用户来说,这不会是一个问题,但需要注意边缘情况。如果表/集合为空,则为字段创建唯一索引:
db.<collection_name>.createIndex({'field':1}, {unique: true})
db..createIndex({'field':1},{unique:true})
如果表/集合不是空的,则删除集合并创建索引:
db.<collection_name>.drop()
db.<collection_name>.createIndex({'field':1}, {unique: true})
db..drop()
db..createIndex({'field':1},{unique:true})
现在重新启动mongoDB。最新答案:根本不需要重新启动mongoDB, 如果colleciton已经有相同的名称索引,mongoose将不会重新创建 您的索引再次出现,因此,首先删除colleciton的现有索引, 现在,当您运行mongoose时,它将创建新索引,
上述过程解决了我的问题。Mongoose在应用程序级别强制执行唯一索引时有点松散;因此,最好使用mongo cli从数据库本身强制执行您的唯一索引,或者在您的UserSchema之后编写以下代码行,明确告诉mongoose您对
unique
索引是认真的:
UserSchema.index({username:1,email:1},{unique:true})代码>
这将在用户架构中的用户名
和电子邮件
字段上强制执行唯一索引。干杯。如果您在以下连接方法中使用选项自动索引:false
:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
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
mongoose.connect(连接字符串,{autoIndex:false})代码>
试着把它去掉。如果这不起作用,请尝试重新启动mongodb,正如本线程中所建议的那样。我做了如下操作:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
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
我添加了Foo.createIndexes()
行b.c。在运行代码时,我收到了以下弃用警告:
(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
我不确定Foo.createIndexes()
是否是异步的,但如果一切正常请检查模式中的自动索引是否为true,当您使用mongoose.connect选项时,它可能会设置为false(默认为true)您可以将模式定义为
User = new Schema ({
email: {
type: String,
unique: true
}
})
但是,如果已经有一个文档,并且在此之后,您已经更改了用户的模式,那么这可能不起作用。如果不想删除此用户集合,可以在电子邮件上为此用户集合创建索引。使用此命令,您可以在电子邮件上创建索引
db.User.createIndex({email:1},{unique: true})
或者,您可以直接删除集合并添加
User = new Schema ({
email: {type: String, unique: true}
});
User.createIndexes();
{
"email": 1
}
db.users.remove({})
const options = {
// your options go here
...
// this code is the solution
audoIndex: true
}
mongoose.connect(DB_URI, options);
let schema = new mongoose.Schema(
{
name: {
type: String,
unique: true,
required: [true, "name required."],
}
}
);
module.exports = mongoose.model("role", schema);