Схема Mongoose: проверка уникального поля, нечувствительного к регистру

У меня есть userSchema так:

var userSchema = new Schema({
    name: {
      type: String
    , required: true
    , validate: [validators.notEmpty, 'Name is empty']
    }
  , username: {
      type: String
    , required: true
    , unique: true
    , validate: [validators.notEmpty, 'Username is empty']
    }
});

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

Правильно ли я считаю, что единственный способ добиться уникальной проверки без учета регистра - написать собственное правило проверки, которое будет выполнять запрос в коллекции? Можно ли так писать проверки проверки, создавая больше подключений к коллекции? Мне нужно будет сделать что-то подобное для email тоже.

Ответ 1

Как насчет использования:

{ type: String, lowercase: true, trim: true }

для достижения вашей цели?

Ответ 2

сопоставление с strength: 2 в индексе решает эту проблему.

index: {
  unique: true,
  collation: {
    locale: 'en',
    strength: 2
  }
}

Поместите это в свой код создания схемы следующим образом:

var userSchema = new Schema({
  ...
  username: {
    type: String,
    required: true,
    index: {
      unique: true,
      collation: { locale: 'en', strength: 2 }
    }
});

Примечание: убедитесь, что индекс модели обновляется - вам может потребоваться сделать это вручную.

Ответ 3

Я не знаю, делаете ли вы это в node. Но вы можете использовать npm следующим образом: https://github.com/blakehaswell/mongoose-unique-validator, чтобы проверить уникальную проверку в полях коллекций. Другим способом может быть проверка коллекции каждый раз, когда появляются новые запросы. http://timstermatic.github.io/blog/2013/08/06/async-unique-validation-with-expressjs-and-mongoose/ Вы можете отсылать материал здесь и использовать его как подходящий для вашего случая.

Ответ 4

Лучший способ - использовать уже существующие пакеты npm, как показано ниже.   https://www.npmjs.com/package/mongoose-unique-validator

Чтобы сделать его чувствительным к регистру, вы можете следить за uniqueCaseInsensitive на той же странице.

Не нужно писать свою собственную логику проверки, если для этого уже есть пакет (далее сообщение Avinash).

Ответ 5

У меня была та же проблема при работе над проектом. Я просто упрощаю это с помощью двух строк кода. преобразование всего входящего значения в маленькие буквы.

let getUsername = req.body.username;
let username = getUsername.toLowerCase();

Ответ 6

Очень простое решение

username : {
        trim:true,
        //lowercase:true,

        type:String,
        required:[true, '{PATH} is required.'],
        match : [
            new RegExp('^[a-z0-9_.-]+$', 'i'),
            '{PATH} \'{VALUE}\' is not valid. Use only letters, numbers, underscore or dot.'
        ],
        minlength:5,
        maxlength:30,
        //unique:true

        validate : [
            function(un, cb){
                console.log(v);
                student.findOne({username:/^un$/i}, function(err, doc){
                    if(err) return console.log(err);
                    if(!_.isEmpty(doc)) return cb(false);
                    return cb(true);
                });
            },
            'Username already exists.'
        ]
    },

Здесь я использую асинхронную проверку и проверку в моей модели student, если такое же поле существует. Использование может, очевидно, использовать регулярное выражение, если вы хотите.

Но я бы не рекомендовал этот метод, он просто не вписывается мне в голову.

Вместо этого примените подход { type: String, lowercase: true, trim: true, unique:true } и скопируйте исходное имя пользователя в другое поле, если оно вам понадобится.

Ответ 7

Я использую mongoose-unique-validator

Пример:

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const { Schema } = mongoose;

const UserSchema = new Schema({
  name: {
    type: String,
    required: true,
    unique: true,
    index: true,
    maxlength: 100,
    trim: true,
    uniqueCaseInsensitive: true
  },
  username: {
    type: String,
    required: true,
    unique: true,
    index: true,
    maxlength: 100,
    trim: true,
    uniqueCaseInsensitive: true
  }
});

UserSchema.plugin(uniqueValidator, {
  message: 'Error, expected {PATH} to be unique.'
});

module.exports = mongoose.model('User', UserSchema);