Выборочная проверка поля, которое проверяет, существует ли поле и активно ли - PullRequest
0 голосов
/ 29 марта 2019

У меня есть коллекция mongodb «Пользователи» с полями «Имя», «Электронная почта», «Активные».Я хочу добавить подтверждение, что для каждого документа электронная почта должна быть уникальной.Однако, если документ недействителен, т. Е. Active имеет значение false, электронное письмо может быть принято.

Вот модель

email: { type: String, validate: {
  validator: function(v) {
    return new Promise((resolve, reject)=> {
      console.log("validating email")
      const UserModel = mongoose.model('User');
      UserModel.find({email : v, active: true}, function (err, docs) 
         {
          if (!docs.length){
              resolve();
          }else{
              console.log('user exists: ',v);
              reject(new Error("User exists!"));
          }
      });
    })
  },
  message: '{VALUE} already exists!'
   }
 },
name: {
  type: String,
  required: true
 },
 active: {
   type: Boolean,
    default: true
 }

Проблема в том, что когда я делаю какие-либо обновления в этой модели, эта проверканазывается.Поэтому, если я обновляю имя, то также вызывается эта проверка, и она выдает ошибку, что электронная почта уже существует.

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

Ответы [ 2 ]

0 голосов
/ 29 марта 2019

Я бы использовал уникальный составной индекс вместо того, чтобы иметь еще один дополнительный запрос к вашей базе данных. Ваш код будет выглядеть так:

const schema = = new Schema(...);

schema.index({email: 1, active: 1}, {unique: true});

Монго сам отклонит ваши документы, и вы можете поймать его в своем коде так:

const {MongoError} = require('mongodb'); // native driver

try {
  await model.updateOne(...).exec(); // or .save()
} catch (err) {
  //11000 is error code for unique constraints
  if (err instanceof MongoError && err.code === 11000)
    console.error('Duplicate email/active pair');
}
0 голосов
/ 29 марта 2019

Сначала я бы вызвал функцию findOne Mongoose, если пользователь уже зарегистрировал базу данных Mongo, например;

let foundUser = await User.findOne({email});
if (!foundUser) {
 // update user, create user etc.
 ...
}

Я думаю, что лучше не использовать логику внутри объекта документа Mongoose. Может быть, есть способ добиться этого, но я предпочитаю делать эти проверки в коде, а не в документе, это просто мое предпочтение.

Также вы можете попробовать сделать электронную почту уникальной:

email: {
  type: String,
  unique: true
}
...