Anonymous
в катчи попадают если выкидывается еррор
Anonymous
сделай проверку на документ, и выкинь сам ошибку
Ivan
привет. торможу и не могу найти в доке, как можно сделать следующее: const candidate = await User.findOne({ email }) - так я ищу по одному полю, чтобы проверить на уникальность. но есть еще поле phone, как можно проверить цепочкой по email и по телефону, чтобы не писать 2 раза const candidate = await User.findOne({ email }) ... const candidate = await User.findOne({ phone })
Anonymous
await User.findOne({ emai, phone })
Ivan
так не пойдет. я же так проверю только то, что пользователя с такими же 2мя полями нет. а если одно совпадет, тогда он пускает
Anonymous
опять чат девелопмент
Anonymous
await User.findOne({ $or: [ {$eq: ["phone", phone]}, {$eq: ["email", email]} ] })
Anonymous
поидеи должно прокатить
Ivan
прикольная конструкция, не знал, спасибо. но все равно работает не так, он не пропускает вообще, даже, когда они точно уникальные оба
Anonymous
а
Anonymous
await User.findOne({ $or: [ {phone: phone}, {email: email} ] })
Nick
привет. торможу и не могу найти в доке, как можно сделать следующее: const candidate = await User.findOne({ email }) - так я ищу по одному полю, чтобы проверить на уникальность. но есть еще поле phone, как можно проверить цепочкой по email и по телефону, чтобы не писать 2 раза const candidate = await User.findOne({ email }) ... const candidate = await User.findOne({ phone })
если вам надо организовать уникальность на уровне базы, то стоит использовать уникальные индексы по вашим полям https://docs.mongodb.com/manual/core/index-unique/ и тогда при попытке добавить связку, которая уже есть в коллекции получите ошибку и дублей вне будет
Anonymous
уже решил
Ivan
уже решил
спасибо большое, так работает)
Ivan
а подскажите еще один момент: у меня в схеме пользователя обязательные поля только name и password. сделано так, чтобы можно было регистрироваться, как зритель, чтобы не бесить его этими регистрациями. провожу такую регистрацию, чтобы он просто попал в базу и потом мог писать сообщения в чат (т.к. модель сообщения содержит реф на юзера). а если человек уже норм регается, тогда он будет вводить и email и телефон и тд тп. но при регистрации зрителя возникают проблемы, т.к. первый зареганный в качестве поля email и phone получается значения null (а эти поля уникальные), то, соответственно, второй уже не может зарегаться, тоже null-и не проходят. как можно это обойти грамотно? не буду же я им генерить рандомные значения туда...
Anonymous
у тя монгус?
Anonymous
в схеме определи как required: false
Anonymous
по умолчанию вроде так и есть
Anonymous
но я обычно пишу, чтоб было видно что это за поле
Ivan
так так и стоит, там дело в том, что я ловлю ошибку mongo e11000 - дубликат уникального поля
Ivan
типа первый зарегался, у него там null-и, а второй пытается - тоже подставляются нули и не пускает, естественно
Anonymous
покажи схему
Ivan
const userSchema = new Schema( { name: { type: String, required: true, minlength: minNameLength, maxlength: maxNameLength, }, password: { type: String, required: true, select: false, minlength: minPasswordLength, }, email: { type: String, unique: true, validate: { validator(string) { return isEmail(string); }, message: wrongEmail, }, }, phone: { type: String, unique: true, }, socialLinks: { type: [ { link: { type: String, validate: { validator(string) { return isURL(string); }, message: wrongLink, }, required: true, }, brandName: { type: String, required: true, }, }, ], default: [], }, avatar: { type: String, validate: { validator(string) { return isURL(string); }, message: wrongLink, }, }, avatarColor: { type: String, }, confirmationLink: { type: String, }, isEmailConfirmed: { type: Boolean, default: false, }, isBlocked: { type: Boolean, default: false, }, role: { type: String, required: true, }, }, { versionKey: false, timestamps: true }, ); module.exports = model('user', userSchema);
Anonymous
попробуй явно указать required: false
Ivan
если можно сослаться на модель на выбор от условия (типа если зареган - на user, если нет - на viewer) - и таких каруселей не было бы...а так я не знаю, как это решить.. когда пользователь должен в базу попасть и при этом указывает только свое имя...
Ivan
так тут в уникальности дело, а не в обязательности)) он просто сам полю нули ставит... или мне делать 2 разных ф-ии, в которых я принимаю разные значения? в одном их них не должно быть email, тогда и проблем не будет?
Ivan
я просто в контроллере принимаю const { name, email, password, phone, socialLinks, avatar, role } = req.body;
Anonymous
спроси у ника
Ivan
блин попробую сейчас и правда два разных метода класса использовать
Anonymous
он знает наверняка
Ivan
а кто это?) я не в теме
Anonymous
@yatoba
Ivan
а понял, окей, спасибо) в личку не стоит, тут тегнуть? или прямо туда можно?
Nick
секунду
Anonymous
лучше тут, я тоже хочу узнать
Nick
позволяет покрывать индексом не все доки а только подмножество, в вашем случае надо будет задать условие что email или phone не равны нулу
Nick
и соответственно на доках у которых выставлено хотя бы мыло или телефон уже будет распространяться требование уникальности
Nick
главное не забывать что null с точки зрения монги это тоже значение и надо именно не проставлять его Sparse indexes only contain entries for documents that have the indexed field, even if the index field contains a null value.
Ivan
понял, спасибо, буду разбираться. а если сделать так, как я в последний раз предложил? ведь если я в контроллере и не буду ждать email и phone, оно не превратится в null-и же в итоге? или я ошибаюсь? я имею ввиду типа того что-то: registrationMember = async (req, res, next) => { try { const { name, email, password, phone, socialLinks, avatar, role } = req.body; const userData = await UserService.registration( name, email, password, phone, socialLinks, avatar, role, ); registrationViewer = async (req, res, next) => { try { const { name, password, role } = req.body; const userData = await UserService.registration( name, password, role, );
Nick
также ест ьвозможност ьиспользовать partial индексы https://docs.mongodb.com/manual/core/index-partial/ - по сути sparce индекс это частный случай partial для услвоия, что поля существуют. В паршиал уже можно задавать разнобразные условия для построения индекса (например индексировать только определенные типы юзеров или только имеющих емейлы)
Anonymous
еслли в монгу передать поле андефаинд оно тоже не появится там
Ivan
понял, спасибо большое вам)
Ivan
нет, так не работает) проверено. он все равно нулл гонит... не знаю, почему...
Ivan
Точно нет
Nick
Тогда partial индекс
Anonymous
а как можно запихнуть пустой объект в пайплайн
Anonymous
мне ругается что элемент пайплайна должен быть корректным, но а если он пустой
Anonymous
Anonymous
Anonymous
можно как-то провернуть такое?
Nick
можно как-то провернуть такое?
собрать пайплайн вручную как обычный массив в js и добавлять через push по условию
Anonymous
охх
Anonymous
код еще хуже станет
Ivan
@yatoba а подскажи, пожалуйста, по этим индексам. Куда такие вещи нужно вставлять вообще? db.users.createIndex( { username: 1 }, { unique: true, partialFilterExpression: { age: { $gte: 21 } } } ) Я просто до этого писал unique: true, монга сама проставляла индексы. Это нужно выполнять в терминале просто или нужно добавить это в объект опций в конце схемы?
Ivan
и соответственно на доках у которых выставлено хотя бы мыло или телефон уже будет распространяться требование уникальности
И вот по этому комментарию: правильно я понял, что пользователь с уникальной почтой, но без телефона и такой же другой для монго будут одинаковы?
Nick
И вот по этому комментарию: правильно я понял, что пользователь с уникальной почтой, но без телефона и такой же другой для монго будут одинаковы?
да, для упрощения понимания можно воспринимать то тут связка email-null с точки зрения сравнения и соответственно для другого юзера с тем же email но также не выставленным телефоном будет выдавать ошибку, но если у второго будет выставлен телефон, то уже поулчится сравнение связки email-null и email-phone и они будут с точки зрения монги разные, хотя email одинаков. Хороший вопрос задал, тут сразу станвоится видно что скорее всего нужны уникальные индексы отдельно по email и отдельно по phone, чтобы как раз избежать такой ситуации
Nick
@yatoba а подскажи, пожалуйста, по этим индексам. Куда такие вещи нужно вставлять вообще? db.users.createIndex( { username: 1 }, { unique: true, partialFilterExpression: { age: { $gte: 21 } } } ) Я просто до этого писал unique: true, монга сама проставляла индексы. Это нужно выполнять в терминале просто или нужно добавить это в объект опций в конце схемы?
там где описывается модель и там же надо через createIndex создавать вручную в коде. Либо отдельно формировать скрипты инициализации бд и вручную или через какиенить CI/CD накатывать, тут уж завимит от ваших заморочек и ведения проектов
Nick
Это можно сделать, использую все тот же частичный индекс, правильно?
нужно делать два раздельных индекса, составной тут не решит эту проблему. И оба можно также сделать partial или sparse
Nick
В я не сталкивался с таким до этого, если честно, поэтому не знаю, как будет лучше
тут я сторонник ручных действий и ручной первичной настройки бд, но это связано с наличием возможности и тем что так действительно проще на тех проектах что я делал (наличие серваков с БД, полного доступа к ней, да еще и админы, которые могли по чек листу пройтись при поднятии БД и ничего не пропустить в части настройки). В коде будет однозначно проще и вы не забудете проинитить базу после очистки. Особенно это упрощает жизнь если вы поднимаете для поиграться монгу в докере каждый раз нулевую без хранения данных
Сын маминой подруги
Нет, это надо не вручную делать, а путем описания миграций
Anonymous
Есть кто живой?
Anonymous
как мне написать вот такое? То есть надо проверить размер массива, и если пустой то вставить пустой массив, иначе первый элемент
Anonymous
все вопрос снят
Ivan
@mxxnseat привет) сделал я разряженные индексы вчера, как господин Ник советовал: выполнил последовательно в терминале монго: db.users.createIndex( { email: 1 }, { unique: true, partialFilterExpression: {email: { $exists: true } } } ) db.users.createIndex( { phone: 1 }, { unique: true, partialFilterExpression: {phone: { $exists: true } } } ) с ними вроде как все работает, можно создать пользователя вообще без поля email и phone, можно с одним из них, можно с обоими, но они независимо должны быть уникальными Только теперь косяк в той проверке, что ты вчера мне подсказал: $or: [{ phone: phone }, { email: email }]. Если я уберу проверку, тогда все ок и монга просто выбрасывает общую ошибку E11000 при дублировании. Но если ее оставить, тогда он неправильно проверяет поля... Не сможешь подсказать, как теперь переписать ее можно?
Anonymous
я не работал еще с уникальными индексами
Anonymous
господин ник