【问题标题】:How to recognize or get the unique field name from mongoose driver with multiple unique fields如何从具有多个唯一字段的猫鼬驱动程序中识别或获取唯一字段名称
【发布时间】:2019-02-13 09:57:46
【问题描述】:

我创建了电子邮件和用户名是唯一的用户架构。当我尝试使用集合中已存在的用户名保存用户时,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(猫鼬驱动程序)会返回相同类型的错误,就像这样。

"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
        }
    });

【问题讨论】:

  • 这是预期的行为。您的错误类型是duplicate key,因为这两个字段都标记为唯一索引。查看显示失败的字段的错误消息。或者,猫鼬错误应该返回一个 path 属性,该属性指向导致错误的特定字段(猜猜你要求什么)。有关更多信息,请查看 mongoose 文档mongoosejs.com/docs/validation.html
  • 我知道错误消息会显示失败的字段,但是我如何通过检查诸如 error_field == 'email or username' 之类的内容来返回错误消息?

标签: mongodb validation mongoose


【解决方案1】:

要获取错误索引(也称为电子邮件或用户名),您必须解析 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'

        }

    }

}

【讨论】:

    【解决方案2】:

    要避免这种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中。

    自动锁定集合或强制单个 连接,没有真正的解决方案。

    对于我们的大多数用户来说,这不会是一个问题,但这是一个边缘情况 请注意。

    【讨论】:

    • 感谢您推荐该插件。干净,是的。
    猜你喜欢
    • 2021-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多