我创建了电子邮件和用户名唯一的用户架构。当我尝试使用集合中已经存在的用户名保存用户时,MongoDb(mongoose驱动程序)将返回以下错误。
"error": {
"driver": true,
"name": "MongoError",
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: todo.users index: username_1 dup key: { : \"sak\" }"
}
但是,当我尝试用集合中已经存在的电子邮件地址保存用户时,MongoDb(mongoose驱动程序)会返回类似类型的错误。
"error": {
"driver": true,
"name": "MongoError",
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: todo.users index: email_1 dup key: { : \"sachin121@gmail.com\" }"
}
这是我的用户架构-
const UserSchema = new mongoose.Schema(
{
email: {
type: String,
lowercase: true,
trim: true,
index: true,
unique: true,
required: true
},
username: {
type: String,
lowercase: true,
trim: true,
index: true,
unique: true,
required: true
},
password: {
type: String,
required: true,
bcrypt: true
},
name: {
type: String,
trim: true,
required: true
}
});
答案 0 :(得分:0)
要获取错误索引(又名电子邮件或用户名),您必须解析errormsg
字符串,并获取错误消息中index:
单词后面提到的属性。
关于此特定讨论存在一个问题,并提出了此答案。看看问题here
有一个负责处理mongoose-unique-validator的节点模块,因此您可以使用它并将该错误作为常规验证错误获取:
{
message: 'Validation failed',
name: 'ValidationError',
errors: {
username: {
message: 'Error, expected `username` to be unique. Value: `JohnSmith`',
name: 'ValidatorError',
kind: 'unique',
path: 'username',
value: 'JohnSmith'
}
}
}
答案 1 :(得分:0)
要避免这种MongoError
类型,可以使用mongoose-unique-validator来检查现有文档中是否存在唯一键。在您的架构中,将此插件用作:
import { Schema } from "mongoose";
const uniqueValidator = require('mongoose-unique-validator');
const UserSchema = new Schema({
email: {
type: String,
lowercase: true,
trim: true,
index: true,
unique: true,
required: true
},
username: {
type: String,
lowercase: true,
trim: true,
index: true,
unique: true,
required: true
},
password: {
type: String,
required: true,
bcrypt: true
},
name: {
type: String,
trim: true,
required: true
}
});
UserSchema.plugin(uniqueValidator, {
type: 'mongoose-unique-validator',
message: 'Error, expected {PATH} to be unique.'
});
在这里,您可以设置自定义消息,也可以从MongoError
更改错误类型,但是此plugin文档中提到了局限性。
因为我们依靠异步操作来验证文档是否 存在于数据库中,有可能在两个查询处执行 同时,两个都返回0,然后都插入到MongoDB中。
除了自动锁定集合或强制单个 连接,没有真正的解决方案。
对于我们大多数用户来说,这不是问题,但是对于 注意。