Anonymous
потому что этоо монга
Dmitry
В какой момент будет меняться индекс, когда выполняется update с $inc по полю из этого индекса? При изменении каждого документа или в конце update, когда уже все документы обновлены?
Viktar
https://docs.mongodb.com/manual/reference/operator/aggregation/filter/#mongodb-expression-exp.-filter
а как отфильтровать элементы в массиве, где нет опрределённого поля? ```db.sales.aggregate([ { $project: { items: { $filter: { input: "$items", as: "item", cond: { $ne: [ "$$item.price", null ] } } } } } ])``` не работает
Maxim
Подскажите как обозначается оператор или?
Anonymous
$or
Viktar
Подскажите как обозначается оператор или?
https://docs.mongodb.com/manual/reference/operator/query/or/
Maxim
спасибо
Dmitry
Всем привет, есть небольшая проблема. Есть коллекция books в которой данные хранятся в некотором виде. У меня задача через lookup получить комментарии и информацию о пользователе, который оставил комvентарий. У меня получилось заменить id на информацию с комментарием и потом id пользователей заменить на их информацию. Но моё решение частично работает т.к. не получается сделать получение информации о пользователе через let и pipeline в lookup. Из-за того, что id может быть в виде строки, по этому и есть необходимость в реализации через let и pipeline. Результат после первого lookup "book":{ //Array<String> _id:..., comments:[ { "_id": "609331be9eaf660870f7115c", "_user": "608b8e66c339f71634642f68", "text": "Какой-то текст" }, ... ] } Частично рабочий вариант: { $lookup: { from: 'users', localField:'comments._user', foreignField:'_id', as: 'comments_user' }} Вариант который по идеи должен работать, но не могу понять почему не работает: { $lookup: { from: 'users', let: {id_temp: "$сomments"}, //"$сomments._user" pipeline: [ {$match: {$expr: { $or:[ {$eq: ["$_id", "$$id_temp"]}, {$eq: ["$_id", { $toString: "$$id_temp" }]} ]} }} ], as: 'comments_user' }}
prrbbttmrrp
привет, как долго устанавливается mongodb?
prrbbttmrrp
уже 40 минут идёт
Андрей
уже 40 минут идёт
Где в представленном процессе установка - стесняюсь спросить?
Null
5.0.3 (Sep 21) • 4.4.9 (Sep 21) ◦ 4.2.16 (Sep 13) ⚠️ Версии 4.4.2-4.4.8 и 5.0.0-5.0.2 содержат критические ошибки в хранилище WiredTiger [1], [2] приводящие к чтению и записи на диск контрольной точки с нарушенной согласованностью данных. Копия данных в памяти остаётся корректной, повреждение происходит при использовании контрольной точки для восстановления данных после аварийного завершения сервера. Что нового в 5.0 (PDF) • Решение проблем с MongoDB по подписке • Документация • Официальные курсы (Бесплатно) Stable: 5.0.3 (Sep 21) Bugfix: 4.4.9 (Sep 21), 4.2.16 (Sep 13) Legacy: 4.0.27 (Sep 13, ☠️Jan ’22) По вопросам размещения вакансий, платной поддержки и покупки лицензий пишите @dd_bb ☠️ 3.6.23 (Mar ’21), 3.4.24 (Jan ‘20), 3.2.22 (Dec ’18), 3.0.15 (May ’17)
Leksey
всем привет! текущая реализация (опустил куски кода с транзакциями): (все при помощи транзакций) const dataProduct = await Product.findOneAndUpdate( { _id: productId }, { $inc: { countActivate: 1 } }, { session, new: true } ); if (countActivate >= 5000) { // пользователь не может купить продукт, т.к. его уже купили 5 тысяч раз // аборт транзакции и завершении сессии // говорим пользователю что товар раскупили } // Если все в порядке, то пользователь купил продукт await ProductBuy.create( [ { userId, productId } ], { session } ); // говорим что пользователь успешно купил товар товары быстро разбирают, максимально быстро около 200-300 RPS пользователи встречают writeConflict (здесь все понятно), можно повторить транзакцию N раз вопрос как можно увеличить скорость покупки товара? может есть иные решения? сейчас при 200-300 RPS около 10 пользователей купят, остальные получат writeConflict хотелось бы избежать повтора транзакций и ускорить процесс покупки
Leksey
всем привет! текущая реализация (опустил куски кода с транзакциями): (все при помощи транзакций) const dataProduct = await Product.findOneAndUpdate( { _id: productId }, { $inc: { countActivate: 1 } }, { session, new: true } ); if (countActivate >= 5000) { // пользователь не может купить продукт, т.к. его уже купили 5 тысяч раз // аборт транзакции и завершении сессии // говорим пользователю что товар раскупили } // Если все в порядке, то пользователь купил продукт await ProductBuy.create( [ { userId, productId } ], { session } ); // говорим что пользователь успешно купил товар товары быстро разбирают, максимально быстро около 200-300 RPS пользователи встречают writeConflict (здесь все понятно), можно повторить транзакцию N раз вопрос как можно увеличить скорость покупки товара? может есть иные решения? сейчас при 200-300 RPS около 10 пользователей купят, остальные получат writeConflict хотелось бы избежать повтора транзакций и ускорить процесс покупки
я искал разные решения 1. менял местами 1) productBuy 2) и далее инкремент количества товара 2. через каунтинг документов не дает гарантию
Leksey
всем привет! текущая реализация (опустил куски кода с транзакциями): (все при помощи транзакций) const dataProduct = await Product.findOneAndUpdate( { _id: productId }, { $inc: { countActivate: 1 } }, { session, new: true } ); if (countActivate >= 5000) { // пользователь не может купить продукт, т.к. его уже купили 5 тысяч раз // аборт транзакции и завершении сессии // говорим пользователю что товар раскупили } // Если все в порядке, то пользователь купил продукт await ProductBuy.create( [ { userId, productId } ], { session } ); // говорим что пользователь успешно купил товар товары быстро разбирают, максимально быстро около 200-300 RPS пользователи встречают writeConflict (здесь все понятно), можно повторить транзакцию N раз вопрос как можно увеличить скорость покупки товара? может есть иные решения? сейчас при 200-300 RPS около 10 пользователей купят, остальные получат writeConflict хотелось бы избежать повтора транзакций и ускорить процесс покупки
есть подозрения, что мне надо будет редис подрубить для каунтинга и проверки 😁
ravia
а есть тут админы которые разворачивали шаред кластер? поделитесь ресурсами где step-by-step расписано толково, а то мне не хватает офф доки
yopp
всем привет! текущая реализация (опустил куски кода с транзакциями): (все при помощи транзакций) const dataProduct = await Product.findOneAndUpdate( { _id: productId }, { $inc: { countActivate: 1 } }, { session, new: true } ); if (countActivate >= 5000) { // пользователь не может купить продукт, т.к. его уже купили 5 тысяч раз // аборт транзакции и завершении сессии // говорим пользователю что товар раскупили } // Если все в порядке, то пользователь купил продукт await ProductBuy.create( [ { userId, productId } ], { session } ); // говорим что пользователь успешно купил товар товары быстро разбирают, максимально быстро около 200-300 RPS пользователи встречают writeConflict (здесь все понятно), можно повторить транзакцию N раз вопрос как можно увеличить скорость покупки товара? может есть иные решения? сейчас при 200-300 RPS около 10 пользователей купят, остальные получат writeConflict хотелось бы избежать повтора транзакций и ускорить процесс покупки
да, делать retry это наиболее корректное решение вашей проблемы при таких условиях
yopp
Если вам необходимо соблюдать порядок, чтоб «честно» распределить заказы между пользователями, то в этом случае вам нужна линеаризация заказов на покупку
Leksey
да, делать retry это наиболее корректное решение вашей проблемы при таких условиях
Т.е. нет варианта ускорить мою конструкцию? Есть конечно вариант, использовать редис для инкремента и проверок числа Конечно, понятно, что документ лочится транзакцией и другая транзакция не может ничего сделать и поможет только retry (бесконечный или N раз), но хотелось бы избежать этого
yopp
т.е. вы делаете бэклог заказов и раз в N секунд этот бэклог в нужном вам порядке обрабатываете
yopp
у вас не получается при такай транзакции больше 300 запросов в секунду?
Leksey
Если вам необходимо соблюдать порядок, чтоб «честно» распределить заказы между пользователями, то в этом случае вам нужна линеаризация заказов на покупку
надо честно, да в моем случае нельзя купить продукт более 5 тысяч раз, иначе беда был бы низким rps - нет проблем при высоком - постоянный writeConflict, retry и длительное ожидание пользователя для покупки
yopp
т.е. важно разделить проблемы: наличие конфликта и производительность
yopp
а «длительное» это в каком диапазоне?
Leksey
т.е. важно разделить проблемы: наличие конфликта и производительность
проблема одна - производительность низкая производительность казалось бы 2 запроса: инкремент и создание записи
Leksey
а «длительное» это в каком диапазоне?
точных замеров нет но в течении 2-3 минут пользователи могут купить 700 раз (4300 не могут соответственно) пользователи получают writeConflict, retry 5 раз у транзакции
yopp
на мой взгляд, наиболее продуктивно будет сначала оценить какие задержки возникают при retry
yopp
если сетевые задержки небольшие, то вероятнее всего речь о порядках сотен миллисекунд
yopp
есть ещё второй вариант: вы можете заранее создать пустые заказы по числу доступных позиций товара
yopp
в этом случае ваш запрос будет покрываться еденичным findAndModify
yopp
там тоже возможны конфликты, но монга их попытается сначала разрешить внутренним ретраем
Leksey
на мой взгляд, наиболее продуктивно будет сначала оценить какие задержки возникают при retry
можно попробовать замерить сделаю сегодня/завтра, попробую понять какие задержки
yopp
но это имеет смысл только если retry в транзакции имеет какое-то существенное влияение
yopp
на мой взгляд существенным будут цифры в десятки секунд
Leksey
есть ещё второй вариант: вы можете заранее создать пустые заказы по числу доступных позиций товара
о, интересно кстати т.е. создали товар на 5 тысяч покупок, сразу забили 5 тысяч покупок (с флагом что не куплено) при покупке - нашли "покупку" (с флагом что не куплено) и изменили
yopp
попробую данный вариант выглядит неплохо
попробуйте сначала понять насколько сильно retry влияет
yopp
возможно проблемы и нет 🙂
Leksey
попробуйте сначала понять насколько сильно retry влияет
т.е. какой показатель нужен? 1 retry - неудача, ушло 10ms 2 retry - неудача, ушло 8ms ... 5 retrry - неудача, ушло 15ms суммарно ушло: 50ms и пользователь не купил в данном формате? правда не понимаю чем мне поможет что конкретно анализировать и что с этим сделать
Leksey
retry на уровне приложения естественно у мен
yopp
хм. т.е. проблема в том, что из 200-300 запросов в секунду только у 10 получается выполнить заказ?
Пол
Привет всем. Подскажите или скиньте где почитать. Есть многомерный массив с объектами, каким способом лучше сравнить с данными в коллекции и заменить два поля. Заранее блогадарен
Viktar
Можно ли в монге сделать процедуру/функцию мне нужно сделать каскадное удаление, для многих сервисов, и делать сервис не вижу смысла, а если встраивать функционал в другие сервисы, то получится дублирование кода и сложно поддерживать в случае изменений
Ivan
привет. подскажите, пожалуйста, не работает unique: true для String поля phoneNumber в схеме. все уже перепробовал и перечитал - не помогает. прикол в том, что в другом проекте у меня это идеально работает с String полем email. я не понимаю, что я мог упустить. реализация идентичная
Viktar
Работу с бд обычно выносят в отдельный слой в котором ты делаешь нужное тебе удаление И да, в таком дублировании ничего страшного нет
Это понятно. Просто сервисов более десятка, которые будут использовать. Плюс не все поддерживаются моей командой. В классической базе я бы написал процедуру и не парился. А в монге что то не могу найти похожий функционал.
Ivan
useCreateIndex: true передаю в опции, так что да
Михаил
Это понятно. Просто сервисов более десятка, которые будут использовать. Плюс не все поддерживаются моей командой. В классической базе я бы написал процедуру и не парился. А в монге что то не могу найти похожий функционал.
Ну не все реляционные базы поддерживают процедуры, это раз Во-вторых, в монге можно в аггрегации функции использовать https://docs.mongodb.com/manual/reference/operator/aggregation/function/ И я не очень понял про число сервисов. У тебе есть сущность a для которой есть коллекция в монге и для работы с этой коллекцией ты делаешь слой, который потом используешь там, где нужно Хочешь в 1 сервисе, хочешь в 100 сервисах Плюс, если ты через монгус работаешь (на ноде), то можешь виртуальные методы использовать
Ivan
я специально сейчас передал поле на email. и все работает. с телефоном нет. может ли быть дело в том, что поле email не имеет пробелов, а phoneNumber имеет?
Михаил
Мне надо каскадное удаление. которое будут использовать много сервисов
В монге нет каскада в принципе. И ты же понимаешь, что "мне нужно каскадное удаление" - это абстрактная вещь Например, у меня есть коллекция А, которая ссылается на коллекцию Б, и есть коллекция В, которая ссылается на коллекцию Г. И если я удаляю Б, я должен удалять А, а если удаляю Г, то должен удалять В. И мне для этого придется 2 функции писать в моем коде, которые это удаление производят.
Михаил
Например в контексте персональных данных
Viktar
Я ответил на вопрос)
нет. Вопрос в том что бы сделать процедуру)) если все эти закидывать в код, сложно поддерживать)
Михаил
нет. Вопрос в том что бы сделать процедуру)) если все эти закидывать в код, сложно поддерживать)
Я ответил 1. Аггрегации, но они на получение данных, ими можно изменять данные в базе но это костыль. 2. Виртуальные методы если монгус есть - но это работает медленнее и принесет при расширение больше проблем. 3. Вручную через код. 4. Не удалять данные, как предложил Никита. 5. Не использовать монгу. Других решений - нет.
Михаил
это была неудачная шутеечка)
Ну, я часто такой вопрос встречаю и все говорят что они не удаляют данные Так что в шутке больше правды, чем шутки)
Ivan
я специально сейчас передал поле на email. и все работает. с телефоном нет. может ли быть дело в том, что поле email не имеет пробелов, а phoneNumber имеет?
нет. он не создает у меня индексов для phoneNumber, а для email создает и все работает.. как можно решить это?
Ivan
двадцать раз уже пробовал)
Cloud
так давай по порядку, у тебя в схеме стоит юник тру для телефона но ты можешь создать записи с одинаковыми телефонами?
Cloud
и индекса для телефона у тебя нет? точнее он не создается
Ivan
да, все верно. хотя я просто изменил названиеполя с phoneNumber на email и все сработало моментально. я не могу это объяснить
Ivan
ради теста
Cloud
скинь скрин схемы плз
Ivan
const userSchema = new mongoose.Schema( { name: { type: String, required: true, }, phoneNumber: { type: String, required: true, unique: true, }, socialLinks: { type: [ { type: String, }, ], default: [], }, avatar: { type: String, }, }, { versionKey: false, timestamps: true } );
Михаил
Номер телефона нужно перед записью в базу стандартизировать
Ivan
я через маску и регулярку на фронте прохожу, по-другому невозможно написать. только так
Максим
это была неудачная шутеечка)
Смотрел как-то доклад один, там мужчина сказал что они вообще ничего не удаляют. Говорит это дорого, дешевле новые диски добавлять.