Задать вопрос

NodeJS + Mongoose. Как генерировать уникальные значения полей документа?

Привет! Есть задача - производить моментальную регистрацию юзеров при вводе только лишь и-мейла. То есть человек вводит свою почту, и сразу входит в личный кабинет, попутно получая письмо с временным паролем и прочими инструкциями, ему так же автоматом присваивается username.

В модели есть два поля (оба уникальные и обязательные), "username" и "email". И-мейл сохраняется как есть (предварительно убедившись, что такого адреса нет у других документов и прочие проверки), а вот юзернэйм должен сначала провериться на уникальность, и в случае, если такой юзернейм уже использован - генерируется новый, с циферкой (username_N). Затем снова идет проверка на уникальность, и если все ок - сохраняется, если нет, то снова генерируется username_N+1 и т.д.

Пока в голову не пришло ничего умнее, как брать из коллекции все документы, у которых username = username.*, затем циклом проходить по всем выбранным, и сравнивать с username_N до тех пор, пока не найдется свободное имя.
  • Вопрос задан
  • 3920 просмотров
Подписаться 4 Оценить Комментировать
Решения вопроса 1
dizballanze
@dizballanze
Software developer at Yandex
Текущий метод не безопасный. Вам нужно делать атомарную операцию с инкрементом.
В mongoose это делается при помощи findOneAndUpdate.
Примерный код будет следующий:

UserSchema.pre "save", function(next) {
    var self = this;
    UrlNameCounter.findOneAndUpdate({username: this.username}, {$inc: {count: 1}}, {upsert: yes},
    function(err, counter) {
        if (counter.count > 1) {
            self.username = self.username + "-" + counter.count;
        }
    })
}


Т.е. вам потребуется дополнительная модель, которая будет хранить счетчики.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
gillbeits
@gillbeits
Если все username идут по сути по порядку, то почему не сделать один только запрос в MongoDB с учетом RegExp в findAll(), потом уже просто добавить +1 к последнему счетчику.
Вариант №2, сделать поле postfix в модели, при совпадении username, просто будет генерироваться новый уникальный постфикс (опять же проверкой не запросами, а уже из выбранных постфиксов.
Ответ написан
@lstdmi
можно еще просто "new date()"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы