Вот мой код:
$catIds = array(7,8,9);
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect("*");
->addAttributeToFilter('category_ids', array('nin' => $catIds));
Я хочу, чтобы все товары отсутствовали в списке идентификаторов категорий, но мой код не дал ожидаемого результата. Пожалуйста, покажи мне путь, спасибо.
Ответы:
Вы должны присоединиться к таблице, которая содержит отношения категории / продукта.
Вариант коллекции, которую я использую, чтобы найти все товары в списке категорий, должен помочь вам:
(не проверено, но вы должны быть на правильном пути)
ссылка: http://www.proxiblue.com.au/blog/Collection_of_products_in_all_child_categories/
источник
Следующий код будет работать для вас:
источник
Я нашел несколько лучший способ сделать это, используя анти-объединение (Magento 1.9).
Преимущества этого подхода
Преимущество этого по сравнению с оригинальным ответом состоит в том, что вы не получите ложных срабатываний, и в результате он быстрее и менее подвержен ошибкам. Например, предположим, у вас есть один продукт:
Вы хотите "найти все товары, которых нет в
category 3
, а затем добавить их вcategory 3
" . Итак, вы запускаетеNOT IN
запрос, и он возвращает две строки(name | category_id)
:Ничего страшного, Magento все равно вернет только первый результат, а затем вы добавите его. Кроме ! Во второй раз, когда этот запрос запускается, вы получаете те же результаты:
И Magento скажет вам, что вы еще не добавили эту рубашку
category 3
. Это связано с тем, что когда товар принадлежит нескольким категориям, он будет иметь несколько строк в таблице «catalog_product_entity» . И такLEFT JOIN
вернет несколько результатов.Это нежелательно, потому что
in_array($categoryThree, $product->getCategories())
), что означает, что вы будете перебирать ненужные результаты. Это замедлит ваш скрипт / код, особенно при больших запасах.Решение
Сгенерированный SQL-запрос будет выглядеть так:
Объяснение:
Учитывая таблицы отношений продукта и категории <=>:
catalog_product_entity
+-----------+ | ENTITY_ID | +-----------+ | 423 | | 424 | | 425 | +-----------+
catalog_category_product
+-------------+------------+ | CATEGORY_ID | PRODUCT_ID | +-------------+------------+ | 3 | 423 | | 123 | 424 | | 3 | 425 | +-------------+------------+
Ваш запрос говорит: «Дайте мне все строки в « catalog_product_entity » и вставьте столбец« category_id »из « catalog_category_product » . Затем просто дайте мне строки, которые category_id = 124" .
Поскольку это левое соединение, в нем всегда будут строки из catalog_product_entity . Для любых строк, которые не могут быть сопоставлены, это будет
NULL
:Результат
+-------------+-------------+ | ENTITY_ID | CATEGORY_ID | +-------------+-------------+ | 423 | NULL | | 424 | 123 | | 425 | NULL | +-------------+-------------+
Оттуда запрос говорит: «Хорошо, теперь дай мне все, где category_id равен NULL» .
источник
Не так просто, как может показаться.
Вот опция на основе GROUP_CONCAT, так как ее предел по умолчанию (1024, но, конечно, может быть увеличен) должен быть в порядке с идентификаторами категорий продуктов, разделенными запятыми.
Кроме того (если вам не нравится GROUP_CONCAT), вы можете использовать WHERE product_id NOT IN, а подзапрос идентификаторов продукта - фактически IN категории, которые вы должны исключить (не давая этого здесь).
Анти-объединение подход из другого ответа также будет работать. Но в этом случае вы не можете легко добавить дополнительные условия.
источник