мангуст: уникальная проверка при обновлении

Проблема

По умолчанию логика валидатора не будет выполняться, когда вы обновляете документ с помощью API обновления мангуста (например, findOneAndUpdate).

Как предлагается в этом ответе, вы можете использовать следующий код в качестве обходного пути:

UserInfo.findOne({ userId: userInfo.userId })
    .then((ui) => {
        ui.set(userInfo);
        return ui.save();
    })

Это работало отлично, пока я не представил mongoose-unique-validator.

мангуст-уникальный-валидатор

Пакет mongoose-unique-validator необходим, потому что без него, если вы нарушите ограничение unique, вы получите расплывчатую ошибку E11000 от mongoDB.

{
    code: 11000
    driver: true
    errmsg: "E11000 duplicate key error collection: archiprod.userinfos index: phone_1 dup key: { : "01234567891" }"
    index: 0
    name: "MongoError"
}

У него есть как минимум две проблемы, когда вы хотите сообщить пользователю, какое поле нарушает ограничение unique.

  • он плохо структурирован, поэтому вам придется извлекать информацию из поля errmsg вручную.
  • Он возвращается только при первом нарушении. Так что если у вас есть два и более нарушений одновременно, вы не сможете показать их все пользователю.

Это больше не проблема с mongoose-unique-validator, потому что вы можете получить следующее структурированное сообщение об ошибке:

{
  "_message": "UserInfo validation failed",
  "errors": {
    "email": {
      "kind": "unique",
      "message": "Error, expected `email` to be unique. Value: `[email protected]`",
      "name": "ValidatorError",
      "path": "email",
      "properties": {
        "message": "Error, expected `email` to be unique. Value: `[email protected]`",
        "path": "email",
        "type": "unique",
        "value": "[email protected]"
      },
      "value": "[email protected]"
    },
    "phone": {
      "kind": "unique",
      "message": "Error, expected `phone` to be unique. Value: `01234567891`",
      "name": "ValidatorError",
      "path": "phone",
      "properties": {
        "message": "Error, expected `phone` to be unique. Value: `01234567891`",
        "path": "phone",
        "type": "unique",
        "value": "01234567891"
      },
      "value": "01234567891"
    }
  },
  "message": "UserInfo validation failed: email: Error, expected `email` to be unique. Value: `[email protected]`, phone: Error, expected `phone` to be unique. Value: `01234567891`",
  "name": "ValidationError"
}