msProducts. Выборка по нескольким опциям
Доброй ночи.
Пытаюсь сделать сложную выборку по группам доп. опций, пока что без особых успехов.
Между опциями должно быть условие «И», внутри каждой опции — «ИЛИ».
Делаю так:
Теперь добавляем вторую группу опций:
Как только во вторую группу добавляются условия, начинаются сложности.
Составляю такой JSON:
Буду благодарен за подсказки и варианты.
Пытаюсь сделать сложную выборку по группам доп. опций, пока что без особых успехов.
Между опциями должно быть условие «И», внутри каждой опции — «ИЛИ».
Делаю так:
&optionFilters=`{
"ps_target:LIKE": "Витрины и мебель",
"OR:ps_target:LIKE": "Ландшафт",
"OR:ps_target:LIKE": "Автомойки"
}`
Все хорошо, в выборке товары, опция «ps_target» которых соответствует какому-либо из 3х значений.Теперь добавляем вторую группу опций:
&optionFilters=`{
"ps_target:LIKE": "Витрины и мебель",
"OR:ps_target:LIKE": "Ландшафт",
"OR:ps_target:LIKE": "Автомойки",
"AND:ps_type:LIKE": "Модульный"
}`
ОК. Выбираются товары с любым из 3х значением ps_target и значением ps_type == Модульный.Как только во вторую группу добавляются условия, начинаются сложности.
&optionFilters=`{
"ps_target:LIKE": "Витрины и мебель",
"OR:ps_target:LIKE": "Ландшафт",
"OR:ps_target:LIKE": "Автомойки",
"AND:ps_type:LIKE": "Модульный",
"OR:ps_type:LIKE": "Ландшафтный",
"OR:ps_type:LIKE": "Карданный"
}`
Не ОК. Выбираются товары с любым из 3х значением ps_target и значением ps_type == Модульный, которые также могут иметь вторым значением ps_type любое из оставшихся значений.Составляю такой JSON:
&optionFilters=`{
"ps_target:IN": [
"Витрины и мебель",
"Ландшафт",
"Автомойки"
],
"ps_type:IN": [
"Модульный",
"Ландшафтный",
"Карданный"
]
}`
Результата нет, в выборке все товары. IN не работает с текстом?Буду благодарен за подсказки и варианты.
Комментарии: 9
Какой запрос получается в логе при &showLog=`1`?
К сожалению, &showLog=`1` абсолютно ничего не выводит.
Разобрался, лог скрывался из-за закоментированных кусков кода, которые у меня использовались между inline-block элементами.
0.0004261: SQL prepared
"SELECT SQL_CALC_FOUND_ROWS `msProduct`.`id`, `msProduct`.`type`, `msProduct`.`contentType`, `msProduct`.`pagetitle`, `msProduct`.`longtitle`, `msProduct`.`description`, `msProduct`.`alias`, `msProduct`.`link_attributes`, `msProduct`.`published`, `msProduct`.`pub_date`, `msProduct`.`unpub_date`, `msProduct`.`parent`, `msProduct`.`isfolder`, `msProduct`.`introtext`, `msProduct`.`richtext`, `msProduct`.`template`, `msProduct`.`menuindex`, `msProduct`.`searchable`, `msProduct`.`cacheable`, `msProduct`.`createdby`, `msProduct`.`createdon`, `msProduct`.`editedby`, `msProduct`.`editedon`, `msProduct`.`deleted`, `msProduct`.`deletedon`, `msProduct`.`deletedby`, `msProduct`.`publishedon`, `msProduct`.`publishedby`, `msProduct`.`menutitle`, `msProduct`.`donthit`, `msProduct`.`privateweb`, `msProduct`.`privatemgr`, `msProduct`.`content_dispo`, `msProduct`.`hidemenu`, `msProduct`.`class_key`, `msProduct`.`context_key`, `msProduct`.`content_type`, `msProduct`.`uri`, `msProduct`.`uri_override`, `msProduct`.`hide_children_in_tree`, `msProduct`.`show_in_tree`, `msProduct`.`properties`, `Data`.`article`, `Data`.`price`, `Data`.`old_price`, `Data`.`weight`, `Data`.`image`, `Data`.`thumb`, `Data`.`vendor`, `Data`.`made_in`, `Data`.`new`, `Data`.`popular`, `Data`.`favorite`, `Data`.`tags`, `Data`.`color`, `Data`.`size`, `Data`.`source`, `Vendor`.`name` AS `vendor.name`, `Vendor`.`resource` AS `vendor.resource`, `Vendor`.`country` AS `vendor.country`, `Vendor`.`logo` AS `vendor.logo`, `Vendor`.`address` AS `vendor.address`, `Vendor`.`phone` AS `vendor.phone`, `Vendor`.`fax` AS `vendor.fax`, `Vendor`.`email` AS `vendor.email`, `Vendor`.`description` AS `vendor.description`, `Vendor`.`properties` AS `vendor.properties`, `120x90`.`url` as `120x90`, `360x270`.`url` as `360x270` FROM `modx_site_content` AS `msProduct`
LEFT JOIN `modx_ms2_products` `Data` ON `msProduct`.`id`=`Data`.`id`
LEFT JOIN `modx_ms2_vendors` `Vendor` ON `Data`.`vendor`=`Vendor`.`id`
LEFT JOIN `modx_ms2_product_files` `120x90` ON `120x90`.`product_id` = `msProduct`.`id`
AND `120x90`.`parent` != 0
AND `120x90`.`path` LIKE '%/120x90/'
LEFT JOIN `modx_ms2_product_files` `360x270` ON `360x270`.`product_id` = `msProduct`.`id`
AND `360x270`.`parent` != 0
AND `360x270`.`path` LIKE '%/360x270/'
LEFT JOIN `modx_ms2_product_options` `ps_target` ON `ps_target`.`product_id`=`Data`.`id`
AND `ps_target`.`key`='ps_target'
LEFT JOIN `modx_ms2_product_options` `ps_type` ON `ps_type`.`product_id`=`Data`.`id`
AND `ps_type`.`key`='ps_type'
WHERE ( `msProduct`.`class_key` = 'msProduct' AND `msProduct`.`parent` IN (2,3,275,348,308,309,310,201,262,279,202,211,226,230,237,241,245,258,260,293,203,206,207,208,209,212,213,214,215,216,217,218,219,220,221,222,223,224,225,227,228,229,231,232,233,234,235,236,286,287,288,289,238,239,240,290,242,243,244,246,247,248,249,250,251,252,253,254,255,256,257,259,261,291,292,294,295,296,297,298,299,263,276,264,265,266,267,269,270,271,272,273,274,300,301,277,278,302,280,9,16,26,33,38,45,53,78,93,108,116,127,137,158,162,199,4,5,6,7,8,281,282,283,284,10,11,12,13,14,15,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,34,35,36,37,39,40,41,42,43,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,79,80,81,83,84,85,86,87,88,89,90,91,92,285,94,95,96,97,98,99,100,101,102,103,104,105,106,107,109,111,112,113,114,115,117,118,119,120,121,122,123,124,125,126,128,129,130,131,132,133,134,135,136,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,159,160,161,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,200,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341) AND `msProduct`.`published` = 1 AND `msProduct`.`deleted` = 0 ) GROUP BY msProduct.id ORDER BY msProduct.id ASC LIMIT 10 "
Вот такой вот запрос
Сейчас посмотрел логи modx, при последнем варианте JSON, выводятся такие ошибки:
[2015-10-08 10:52:14] (ERROR @ /index.php) Error parsing condition with key 0: `ps_target`.`value`INArray
[2015-10-08 10:52:14] (ERROR @ /index.php) Error parsing condition with key 1: `ps_type`.`value`INArray
Попробуйте заменить сниппет msProducts на такой: gist.githubusercontent.com/argnist/706335bdeddc521f3b31/raw/d916f8f48df2aa97f3b1af44666587312e52e3e8/snippet.ms_products.php
Спасибо за уделенное внимание.
Ошибки в логах modx те же, но теперь на сайте не отображаются результаты работы модифицированного сниппета msProducts — ни товаров, ни лога.
+, если какое в какой-то из опций не выбрано ни одного варианта, в логе modx добавились такие ошибки:
Ошибки в логах modx те же, но теперь на сайте не отображаются результаты работы модифицированного сниппета msProducts — ни товаров, ни лога.
+, если какое в какой-то из опций не выбрано ни одного варианта, в логе modx добавились такие ошибки:
[2015-10-08 17:16:01] (ERROR @ /index.php) Encountered empty IN condition with key `value`
[2015-10-08 17:16:01] (ERROR @ /index.php) [pdoTools] Error 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND `ps_type`.`value` IN ('ЖКХ') ) AND `msProduct`.`parent` IN (2,3,275,34' at line 1
Столкнулся с похожей проблемой, нужно было получить товары по нескольким значениям одной опции (версия miniShop2 2.2.0-beta4). Проблема была решена копированием сниппета msProducts и изменением строчек 98-114:
На следующие:
Решение «в лоб», но в условиях когда «еще вчера все должно было работать» годится.
if (!is_string($value)) {
if (!empty($conj)) {
$last_where = end($opt_where);
if (is_array($last_where)) {
$conj = !empty($conj) ? $conj.':' : '';
$opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
} else {
array_splice($opt_where, -1, 1, $last_where . " {$conj} `{$key}`.`value`{$operator}{$value}");
}
} else {
$opt_where[] = "`{$key}`.`value`{$operator}{$value}";
}
} else {
$conj = !empty($conj) ? $conj.':' : '';
$opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
}
На следующие:
if (is_string($value) || is_array($value)) {
$conj = !empty($conj) ? $conj.':' : '';
$opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
} else {
if (!empty($conj)) {
$last_where = end($opt_where);
if (is_array($last_where)) {
$conj = !empty($conj) ? $conj.':' : '';
$opt_where[] = array("{$conj}`{$key}`.`value`:{$operator}" => $value);
} else {
array_splice($opt_where, -1, 1, $last_where . " {$conj} `{$key}`.`value`{$operator}{$value}");
}
} else {
$opt_where[] = "`{$key}`.`value`{$operator}{$value}";
}
}
Решение «в лоб», но в условиях когда «еще вчера все должно было работать» годится.
Спасибо за ценную информацию.
Прошу прощения за некромантию, но может кому-то пригодится решение без модификации сниппета, на вышеуказанном примере, без использования leftJoin:
&optionFilters=`{
"ps_target:!=":"",
"ps_type:!=":""
}`
&where=`["
(ps_target.value='Витрины и мебель' OR ps_target.value='Ландшафт' OR ps_target.value='Автомойки') AND
(ps_type.value='Модульный' OR ps_type.value='Ландшафтный' OR ps_type.value='Карданный')
"]`
по сути optionFilters подключает нужные таблицы и дает не противоречащие условия, а все остальное прописывает внутри where
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.