Как сделать быструю сортировку и фильтрацию товаров в bitrix с учетом скидок которые указаны в правилах корзины?
В bitrix проекте в карточке товара с торговыми предложениями выводится цена с учетом скидки. Когда 100 торговых предложений это работает быстро, но когда их больше 1000 то страница может грузиться 3 секунды и больше. Все дело в том что мы из базы получаем все 1000 товаров, из за этого страница медленно грузится. Казалось бы тревиальная задача, можно просто при загрузке страницы выводить одно торговое предложение, потом клиент нажимая на select или checkbox выбирает нужное торговое предложение которое подтягивается c помощью ajax. Но допустим нам нужно вывести товар с самой маленькой стоимостью с учетом скидки, к сожалению правила корзины в bitrix устроены так, что для получения товара с маеньшей ценой надо прогнать в цикле все 1000 товаров и определить какая получается скидка у каждого товара, а это не избежно приведет к медленной загрузке странице. Было несколько идей как такое реализовать:
1) Сделать индексацию скидок например через сервис очередей, запускать задачу которая проганяет все товары по скидкам и получает меньшую цену. Недостаток тут в том, что это бы плохо работало для скидок которые рассчитаны на конкретного пользователя, получается нам бы пришлось еще прогонять все товары для всех пользователей, что бы узнать скидку. Или прогонять все товары по скидкам для конкретного пользователя, что опять же замедлит запрос если делать на лету или же клиент будет ждать пока сервис очередей высчитает скидку.
2) Сделать супер огромный sql запрос который бы фильтровал товары такому же алгоритму как это делают правила корзины в bitrix. Тут проблема в том что не хотелось бы вдаваться в детали реализации правил корзины, как минимум это приведет к дублированию логики, так как в bitrix скидки считаются на php, нам бы пришлось это еще на sql делать. Плюс нет гарантии что получиться без ошибок сделать копию логики на sql запросе. Скорее всего будут баги и много не учтенных сценариев.
3) Сделать свою логику скидок, и подстроить под себя для удобства. Тут минус в том что bitrix предлагает и так уже впринципе не плохой инструмент для работы со скидками, делая свои скидки мы не гарантируем их гибкость такую же как в битриксе или же сделав по аналогии со скидками битрикс, также получится огромный sql запрос, со сложной логикой.
Может у кого то была такая задача, как вы ее решали? Как вообще грамотно сделать быструю фильтрацию с учетом скидок, логика которых может быть написана на php к примеру?
ArrayPop, ну когда пользователь логониться в систему - надо запустить процесс подготовки сета документов (JSON) по скидкам. Для каждого виджета который тормозит или медленно обновляется - надо подготовить такой документ. И отдавать его из NGinx.
Чтоб документы не устаревали надо задать им время жизни (5 - 30 минут например)
и прописать expired.
Более интересный вариант - использовать теги If-Modified-Since. Если существует быстраа и дешевая
проверка на устаревание документа скидка-пользователь то можно это использовать.
mayton2019, ну это и есть индексация, мы пытаемся заранее рассчитать скидки, потом быстро их отдавать поьзователю. Скидка для пользователя может начать срабатывать после определенных действий, к примеру когда пользователь подписался на какую то рассылку. Нам получается надо запустить индексацию после того как пользователь подписался, допустим эта индексация занимает 30 секунд или минуту, и она работает в фоновом режиме. Получиться что пользователь подписался и пошел на страницу товара, скидка уже должна бы показать товар с учетом его скидки, но индексация еще не закончилась, ему еще сколько то секунд надо подождать, актуализация в таком случае сильно страдает.
А зачем расчитывать скидки для конкретного пользователя? Рассчитывайте для групп пользователей. Цену для каждой группы пишите в отдельное свойство, и выполняйте сортировку именно по этому полю.
Роман Грицук, можно и для групп пользователей, это особого значения не имеет. Факт что при наступлении некоторого события (действия пользователя) включится определенная скидка. Да, самое простое это добавить цену в свойство, но мы так дублируем данные, администратор должен помимо создания правила корзины еще добавить в свойства всех товаров эту цену. Это еще хорошо если у нас 2 скидки. Но в bitrix мы же можем сделать 300 правил корзины, у каждой такой скидки есть свой приоритет на выполнение, то есть не факт что вообще какая то скидка отработает, а мы делаем соритровку по свойству с ценой, и не известно вообще отработала скидка или нет. Получается админу надо учесть это и знать заранее какая скидка за какой идет по очереди и какая выполниться.
администратор должен помимо создания правила корзины еще добавить в свойства всех товаров эту цену
зачем это перекладывать на человека? напишите скрипт, который будет сам заполнять эти свойства средствами php, используя API bitrix. Да повесьте его на cron