NodeJS + Mongoose. Как генерировать уникальные значения полей документа?
Привет! Есть задача - производить моментальную регистрацию юзеров при вводе только лишь и-мейла. То есть человек вводит свою почту, и сразу входит в личный кабинет, попутно получая письмо с временным паролем и прочими инструкциями, ему так же автоматом присваивается username.
В модели есть два поля (оба уникальные и обязательные), "username" и "email". И-мейл сохраняется как есть (предварительно убедившись, что такого адреса нет у других документов и прочие проверки), а вот юзернэйм должен сначала провериться на уникальность, и в случае, если такой юзернейм уже использован - генерируется новый, с циферкой (username_N). Затем снова идет проверка на уникальность, и если все ок - сохраняется, если нет, то снова генерируется username_N+1 и т.д.
Пока в голову не пришло ничего умнее, как брать из коллекции все документы, у которых username = username.*, затем циклом проходить по всем выбранным, и сравнивать с username_N до тех пор, пока не найдется свободное имя.
Текущий метод не безопасный. Вам нужно делать атомарную операцию с инкрементом.
В mongoose это делается при помощи findOneAndUpdate.
Примерный код будет следующий:
Спасибо, то что нужно, хотелось как раз все это сделать именно на уровне модели, средствами самого Mongoose. А можно поподробне про небезопасность моего варианта?
@rshashkov небезопасность в том, что в один и тот же момент времени теоретически 2 запроса могут получить одинаковые данные соответственно 2 одинаковых идентификатора. Атомарные операции позволяют от этого защититься.
Если все username идут по сути по порядку, то почему не сделать один только запрос в MongoDB с учетом RegExp в findAll(), потом уже просто добавить +1 к последнему счетчику.
Вариант №2, сделать поле postfix в модели, при совпадении username, просто будет генерироваться новый уникальный постфикс (опять же проверкой не запросами, а уже из выбранных постфиксов.