Как исключить категорию из magento getCollection - PullRequest
2 голосов
/ 02 марта 2012

это может быть глупый вопрос, но хорошо. У меня есть следующий код, который возвращает все товары из моего магазина.

$products = Mage::getModel('catalog/product')->getCollection();
$products->addAttributeToFilter('status', 1);
$products->addAttributeToFilter('visibility', 4);
$products->addAttributeToFilter('type_id', 'simple');
$products->addAttributeToSelect('*');
$products->addStoreFilter($storeId);
$prodIds = $products->getAllIds();

Мне известно о:

$category = Mage::getModel('catalog/category')->load(9);
$products->addCategoryFilter($category);

для фильтрации по идентификатору категории, но как получить для всех продуктов кроме один конкретный идентификатор категории? (Magento 1.6.2)

Ответы [ 3 ]

3 голосов
/ 02 марта 2012

Я думаю, что это должно сработать, предполагая, что вы знаете, какой идентификатор категории вы хотите отфильтровать, но я не могу проверить это прямо сейчас

$catId = 9;

/* I'm almost positive 'e' is the alias used for catalog_product_entity, check your
   query with echo (string) $products->getSelect(); if it doesn't work */
$products->getSelect()->join(array('cats' => 'catalog_category_product'), 'cats.product_id = e.entity_id');
$products->getSelect()->where('cats.category_id', array('neq' => $catId));
1 голос
/ 18 марта 2015

Вот что я использовал:

$_productCollection = Mage::getModel('catalog/product')
        ->getCollection()
        ->addAttributeToSelect('*')
        ->addUrlRewrite();

Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($_productCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($_productCollection);

$_productCollection->load();
$_productCollection->getSelect()->join(array('cats' => 'catalog_category_product'), 'cats.product_id = e.entity_id');
$_productCollection->getSelect()->where('cats.category_id not in (41)');
0 голосов
/ 19 июля 2015

Вот логика, которую я придумал, чтобы решить эту проблему.

Примечание. Должно работать в Magento 1.X

  1. . Оно динамически извлекает имена таблиц, чтобы оно работало в любой установке.
  2. Проверяет, что этоправильный catalog/category идентификатор объекта.
  3. Используется уникальный псевдоним таблицы по идентификатору категории при выполнении MySQL LEFT JOIN.Это позволяет нам исключить коллекцию из нескольких идентификаторов категорий.
  4. Это подтверждает, что мы не пытаемся исключить коллекцию из одного и того же идентификатора категории дважды.

    public function addCategoryExclusionFilter(Mage_Catalog_Model_Resource_Product_Collection $collection, $category_id)
    {
        /* @var $resource Mage_Core_Model_Resource */
        /* @var $category Mage_Catalog_Model_Category */
        $resource = Mage::getModel('core/resource');
        $category = Mage::getModel('catalog/category')->load($category_id);
        $select   = $collection->getSelect();
        $tblccp   = $resource->getTableName('catalog_category_product');
        $tblAlias = $tblccp.'_'.$category_id;
    
        if (! $category->getId()) {
            Mage::throwException("Invalid `{$resource->getTableName('catalog/category')}`.`entity_id` value ({$category_id}).");
        }
    
        if (strpos($select->__toString(), $tblAlias) !== false) {
            Mage::throwException("Category (ID: {$category->getId()}) already excluded from collection");
        }
    
        $select->joinLeft(array($tblAlias => $tblccp), "(`{$tblAlias}`.`product_id` = `e`.`entity_id` AND `{$tblAlias}`.`category_id` = '{$category->getId()}')", array());
        $select->where("`{$tblAlias}`.`category_id` IS NULL");
    }
    

Пример запроса MySQL впоследствии:

SELECT 
    `e`.* 
FROM
    `catalog_product_entity` AS `e`
LEFT JOIN
    `catalog_category_product` AS `catalog_category_product_28` ON (
        `catalog_category_product_28`.`product_id` = `e`.`entity_id` AND
        `catalog_category_product_28`.`category_id` = '28'
    ) 
WHERE 
    (`catalog_category_product_28`.`category_id` IS NULL)

Здесь мы выполняем соединение таблицы, в которой хранятся отношения между сущностями продукта и сущностями категории, НО только там, где запись category_id равен идентификатору категории, который мы хотим исключить.Это важно, потому что таблица catalog_product_entity имеет отношение 1: M к таблице catalog_category_product (на момент публикации этого ответа я не вижу здесь других ответов на этот вопрос).Затем мы добавляем декларацию WHERE, в которой нам нужно только выбрать записи, в которых столбец category_id для объединенной таблицы равен NULL (поскольку в объединенной таблице нет записей для сущностей продуктов, которые мы хотим выбрать).

...