Сложная выборка по TV параметрам в getResources
Доброго времени суток, сообщество!
Хочу поделиться одним небольшим трюком, который позволяет устранить одну, на мой взляд нелогичность в getResources
Как известно, для того чтобы отфильтровать товары (или ещё какие оъекты) по TV параметрам следует использовать tvFilters
Если нам нужно отобрать товары Sony с диагональю 65 или 85 дюймов придётся использовать такую конструкцию
А теперь представим, что нам нужно отобрать товары Sony с диагональю 65 или 85 дюймов черного или серого цвета
Если мы добавим в условие ещё один цвет или размер диагонали начнётся жесть
Дело в том, что при разборе параметра &tvFilters, getResources делит запрос на операторы или (||), а потом на операторы и (,)
На практике же, гораздо чаще требуется, чтобы порядок был обратным
Чуть-чуть подправим getResources
120 строка
Меняем
256 строка
Меняем
312 Строка
Меняем
Таким нехитрым способом гораздо проще реализовывать сложные фильтры, наподобие таких, как реализованы на сайтах Евросети и Эльдорадо
Хочу поделиться одним небольшим трюком, который позволяет устранить одну, на мой взляд нелогичность в getResources
Как известно, для того чтобы отфильтровать товары (или ещё какие оъекты) по TV параметрам следует использовать tvFilters
[[getResources? &tvFilters=`manuf===Sony||manuf===LG`]]выбрать товары Sony или LG (можно так: manuf===LG||Sony)[[getResources? &tvFilters=`diag===65||diag===85`]]выбрать товары с диагональю 65 или 85 дюймов[[getResources? &tvFilters=`manuf===Sony,diag===65`]]выбрать товары Sony c диагональю 65 дюймЕсли нам нужно отобрать товары Sony с диагональю 65 или 85 дюймов придётся использовать такую конструкцию
[[getResources? &tvFilters=`manuf===Sony,diag===65||manuf===Sony,diag===85`]]А теперь представим, что нам нужно отобрать товары Sony с диагональю 65 или 85 дюймов черного или серого цвета
[[getResources? &tvFilters=`manuf===Sony,diag===65,color===black||manuf===Sony,diag===65,color===gray||manuf===Sony,diag===85,color===black||manuf===Sony,diag===85,color===gray`]]Если мы добавим в условие ещё один цвет или размер диагонали начнётся жесть
Дело в том, что при разборе параметра &tvFilters, getResources делит запрос на операторы или (||), а потом на операторы и (,)
На практике же, гораздо чаще требуется, чтобы порядок был обратным
[[getResources? &tvFilters=`manuf===Sony,diag===65||85,color===gray||black`]]согласитесь такая конструкция куда проще, чем та, которая выше и добавление ещё одного условия не составит труда Чуть-чуть подправим getResources
120 строка
Меняем
$tvFilters = !empty($tvFilters) ? explode($tvFiltersOrDelimiter, $tvFilters) : array();На $tvFilters = !empty($tvFilters) ? explode($tvFiltersAndDelimiter, $tvFilters) : array();256 строка
Меняем
$filters = explode($tvFiltersAndDelimiter, $tvFilter);На$filters = explode($tvFiltersOrDelimiter, $tvFilter);312 Строка
Меняем
if (!empty($conditions)) {
$firstGroup = true;
foreach ($conditions as $cGroup => $c) {
if (is_array($c)) {
$first = true;
foreach ($c as $cond) {
if ($first && !$firstGroup) {
$criteria->condition($criteria->query['where'][0][1], $cond, xPDOQuery::SQL_OR, null, $cGroup);
} else {
$criteria->condition($criteria->query['where'][0][1], $cond, xPDOQuery::SQL_AND, null, $cGroup);
}
$first = false;
}
} else {
$criteria->condition($criteria->query['where'][0][1], $c, $firstGroup ? xPDOQuery::SQL_AND : xPDOQuery::SQL_OR, null, $cGroup);
}
$firstGroup = false;
}
}На if (!empty($conditions)) {
$firstGroup = true;
foreach ($conditions as $cGroup => $c) {
if (is_array($c)) {
$first = true;
foreach ($c as $cond) {
if ($first && !$firstGroup) {
$criteria->condition($criteria->query['where'][0][1], $cond, xPDOQuery::SQL_AND, null, $cGroup);
} else {
$criteria->condition($criteria->query['where'][0][1], $cond, xPDOQuery::SQL_OR, null, $cGroup);
}
$first = false;
}
} else {
$criteria->condition($criteria->query['where'][0][1], $c, $firstGroup ? xPDOQuery::SQL_OR : xPDOQuery::SQL_AND, null, $cGroup);
}
$firstGroup = false;
}
}Таким нехитрым способом гораздо проще реализовывать сложные фильтры, наподобие таких, как реализованы на сайтах Евросети и Эльдорадо
Комментарии: 13
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
За сколько у тебя грузится страница с результатами такой фильтрации?
Много?
Заметил, что чем мягче условия поиска, тем дольше приходит ответ. Т.е если сбросить все фильтры, то ответ приходит за секунду. Если составить условия таким образом, что в результате на вывод будет всего пара записей, то ответ сервера 0.3 сек
В базе сейчас примерно 2500 записей
Мне, в своё время, скорость работы getResources показалась неприемлимой.
Ознакомился с документацией pdoTools, но не нашёл там ответ
Конкретно меня интересует возможность смены приоритета работы операторов И и ИЛИ в tvFilters
В принципе, там есть и &tvFilters, но только как временная замена при миграции c getResources. Пользоваться этим параметром я никому не советую — &where гораздо гибче, лучше и удобнее.
Вот здесь кратко написано, а вот здесь значительно подробнее.
Буду пробовать.
Ещё маленький вопросик можно?
Если в OR нам нужен LIKE?
— мне почему-то кажется, что такая констукция работать не будет
Такое нужно например когда мы используем multiselect TV
Как быть тогда?
Но можно указывать строки:
Подробнее про синтаксис where можно прочитать в официальной документации.
И очень тебя прошу — почини свой enter, ненужные пустые строки в комментарии выглядят неопрятно.
У тебя — просто строка со скобочками, которая вовсе не раскодируется как JSON. Верный код:
И если я ничего не путаю, то при вызове из PHP можно вообще не париться с JSON, а указывать просто массив вот так:
Но не факт — нужно проверять.
Ситуация у меня следующая. С помощью getResources, описанным в посте способом, я получаю список объектов. Он выводится у меня постранично. На против каждого объекта есть чекбокс. Ещё есть форма-фильтр. Мне нужно отметить чекбоксы всех записей, которые соответствуют фильтру, а их на данный момент может быть до 2500.
Изначально я сделал всё на getResources. Всё работает. Теперь же решил ускорить работу и для выделения чекбоксов решил использовать ajax с pdoResources.
Теперь я могу визуально наблюдать разницу между getResources и pdoResources. Есть ряд записей, которые pdoResources мне не возвращает, хотя они соответствуют условию фильтра, и тот же getResources мне их отдаёт
А в остальном должно всё работать.
Проверил, действительно у неотмеченных записей проставлены значения по умолчанию. Буду искать способ как автоматом проставить все записи по умолчанию