【问题标题】:Unique validation not working in Mongoose唯一验证在 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 当然,没问题。已更新。

标签: javascript node.js mongodb mongoose


【解决方案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)在邮递员中测试,你会看到比现在更有效

干杯。

【讨论】:

【解决方案3】:

连接数据库时使 autoIndex: true。

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

【讨论】:

    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2015-04-04
    • 1970-01-01
    • 2017-06-29
    • 2014-07-29
    相关资源
    最近更新 更多