如何从magento getCollection中排除类别

时间:2012-03-02 18:00:28

标签: magento filtering

这可能是一个愚蠢的问题,但很好。我有以下代码来检索我店里的所有产品。

$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);

按类别ID过滤,但如何将所有产品一个特定类别ID? (Magento 1.6.2)

3 个答案:

答案 0 :(得分:3)

我认为这应该有效,假设您知道要过滤的类别ID,但我现在无法测试

$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 :(得分:1)

这就是我使用的:

$_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)');

答案 2 :(得分:0)

以下是我提出的解决此问题的逻辑。

注意:应该在Magento 1.X

中工作
  1. 它动态提取表名,以便在任何安装中都可以使用。
  2. 验证它是正确的catalog/category实体ID。
  3. 在执行MySQL LEFT JOIN时,它按类别ID使用唯一的表别名。这允许我们从多个类别ID中排除集合。
  4. 它验证我们不会尝试两次从同一类别ID中排除该集合。

    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");
    }
    
  5. 之后的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等于我们正在查找的类别ID的位置排除。这很重要,因为catalog_product_entity表与catalog_category_product表的关系为1:M(在发布此答案时,我没有看到其他答案解决此问题)。然后,我们添加一个WHERE声明,我们只想选择连接表的category_id列为空的记录(因为在连接表中没有记录,对于我们希望选择的产品实体)。 / p>