唯一验证在 Mongoose 中不起作用

Posted

技术标签:

【中文标题】唯一验证在 Mongoose 中不起作用【英文标题】:Unique validation not working in Mongoose 【发布时间】:2016-09-11 00:10:11 【问题描述】:

我知道这个问题有 been asked before,但似乎没有一个解决方案适合我。

我有一个这样定义的简单模型:

const mongoose = require('mongoose')
const  Schema  = mongoose

let subscriberSchema = new Schema(
  firstName:  type: String, required: true ,
  email:  type: String, required: true, unique: true 
,  timestamps: true )

let Subscriber = mongoose.model('Subscriber', subscriberSchema)

如果我运行以下命令(在 REPL 中,因此没有异步问题),我希望看到第二次调用 create 时记录错误。

Subscriber.create( firstName: "Landon", email: "example@example.com" )
Subscriber.create( firstName: "Landon", email: "example@example.com" , function(err)  
  console.log("ERROR", err) 
)

相反,我看到的是"ERROR" null

如果我运行count 查询或find 查询,我可以看到两个模型都已创建。我做错了什么?

编辑

以下是我已经尝试过的一些事情:

添加索引后重启 MongoDB 删除所有现有记录,以便不存在可能违反唯一性约束的现有记录 通过所有这些方式定义email 属性(我在不同的地方看到了不同的实现): type: String, required: true, unique: true type: String, required: true, index: true, unique: true type: String, required: true, index: unique: true

【问题讨论】:

您能否编辑您的问题以包含您通过链接问题检查的内容,这样我们就不必问同样的问题? @JohnnyHK 当然,没问题。已更新。 【参考方案1】:

这是用 node 解决的非常复杂的事情,因为你知道它是异步的。 如果您同时运行两个查询,则两者都将检查 doc 是否同时存在并且都将尝试创建记录。

你可以做两件事。

创建唯一索引

YourModel.index( email: 1,  unique: true )

或 通过 $setOnInsert 使用更新

var pk = email : 'your email';
YourModel.update(pk, 
        $setOnInsert : data
    , upsert : true)

并确保索引存在于 mongoDB 中。

Mongoose 不会修改键集上的索引。首先尝试从 mongo shell 中删除索引。

 db.collection.dropIndex(email : 1)

重新启动节点进程,mongoose 现在将创建具有唯一约束的索引。

【讨论】:

我认为我的问题并不清楚。示例 Subscriber.create 调用位于 Node REPL 中,因此不应该存在任何异步问题。我运行了第一个创建,等待它完成,然后运行第二个。如果我稍后再调用create,我仍然会看到同样的问题。 每当你添加索引时,你必须重启节点进程,Mongoose autoIndex 会尝试确保索引。您可以通过 mongoose 调试来看到这一点。并确保索引在 getIndexes() 的集合中 我试过重启服务器和mongod,但不幸的是这似乎没有帮助。运行Scheduler.collection.getIndexes() 解析为: _id_: [ [ '_id', 1 ] ], email_1: [ [ 'email', 1 ] ] 。我没有看到任何关于独特性的内容,但我不确定我是否应该这样做,而且我不知道如何解决它。 哦,我知道了,mongoose 不会修改一个键集上的索引,您必须从 shell 中使用 dropIndex 删除索引。然后你会看到唯一索引 我已经更新了我的答案,如果它适合你,请接受。【参考方案2】:

实际上,验证工作的唯一选项,如何?请按照以下步骤操作: 1) 设置唯一性:对于架构中的某些字段为 true(例如“电子邮件”) 2) 删除整个数据库 3)重启节点服务器 4)在邮递员中测试,你会看到比现在更有效

干杯。

【讨论】:

在对相同的格式进行了两次编辑后,我不得不请您尝试发布不太相似的答案。 ***.com/a/64192781/7733418 了解 Yunnosch。【参考方案3】:

连接数据库时使 autoIndex: true。

mongoose
.connect('connection url', 
    useUnifiedTopology: true,
    useNewUrlParser: true,
    autoIndex: true, //make this true
)
.then(() => 
    console.log('Connected to mongoDB');
);

【讨论】:

以上是关于唯一验证在 Mongoose 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

SetTimeout 在 Mongoose 模式后中间件中不起作用

更新对象数组中的元素在 Mongoose 中不起作用

比较 Mongoose 对象 ID 时,if 语句在 Jade 中不起作用

从 Rest(Express) 迁移到 GraphQL:模型(mongoose) 在 graphQL 解析器中不起作用

唯一属性不起作用 mongoose 重复项仍在添加中

Mongoose 所需的真实验证不起作用