Magento - joinField()查询将store_id添加到集合中的产品

时间:2011-05-16 12:48:34

标签: magento

我几个月来一直试图通过它的商店根类别来过滤产品系列。我尝试过多种不同的方式(Magento - addStoreFilter not working?Magento ->addCategoryFilter - filtering product collection by root categoryMagento - Loading root collection loads all products),但仍未找到任何可行的方法。

所以我想尝试将store_id添加到集合中的产品中。我可以使用以下方法调用该集合,但我需要加入一些字段以添加store_id:

$_testproductCollection = Mage::getResourceModel('catalog/product_collection');
$_testproductCollection->getSelect()->distinct(true);
$_testproductCollection->addAttributeToSelect('*')->load();

我需要的joinField类似于以下内容(在上面链接的帖子中给出)但 store_id = 1 部分将每个产品store_id更改为1,我不想要,我只是想要一种方法来添加它的指定商店,这样我就可以通过它进行过滤。

$_testproductCollection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left');

有人能指出我正确的方向吗?干杯!

3 个答案:

答案 0 :(得分:2)

我可以想一下子查询的方法。以下摘录摘自我正在研究的图书馆。它们放在lib/目录中,因此自动加载器可以访问它们。我还没有分析性能,但我的直觉告诉我MySQL将分别缓存子查询,所以当重用时,他们的结果很好而且快速。如果性能不太好,我可能必须将它们作为数据库视图来实现。

这种技术的关键是理解Zend的选择可以直接用作SELECT,FROM或WHERE子句,并自动成为子查询。

// A shortened example, not tested directly
class Example_Product_List extends Varien_Db_Select {

    protected $_resource;

    public function __construct($storeId) {
        // Since this isn't a collection we need to get the resource ourselves
        $this->_resource = Mage::getSingleton('core/resource');
        $adapter = $this->_resource->getConnection('core_read');
        parent::__construct($adapter);

        $this->from(
            array('catprod'=>$this->getTable('catalog/category_product')),
           'product_id'
        );
        $this->joinInner(
            array('catprodin'=>$this->getTable('catalog/category_product_index'),
            '(catprodin.category_id=catprod.category_id) AND (catprodin.product_id=catprod.product_id)',
            'store_id'
        );
        $this->where('store_id = ?', $storeId);
        $this->group('product_id');
    }

    public function getTable($modelEntity)
    {
        return $this->_resource->getTableName($modelEntity);
    }

}

// Using it in a collection
class Example_Module_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4 {

    protected function setStoreId($store) {
        $this->getSelect()->where(array(
            'attribute'=>'product_id',
            'in'=>new Example_Product_list($store->getId())
        );
        return parent::setStoreId($store);
    }
}

// Putting it to use, '1' can be any store ID.
$_testproductCollection = Mage::getResourceModel('examplemodule/product_collection');
$_testproductCollection->addStoreFilter(1);
$_testproductCollection->addAttributeToSelect('*')->load();

接近结束时,我使用继承的addStoreFilter()因为我不仅要包含正确的产品,还要使用商店的适当值。如果您的商店已翻译产品名称,则采用正确的名称。

基本上整个事情是构建商店所有产品的列表(非常大,这就是为什么我希望它能很好地缓存)然后有效地做“WHERE product_id IN(list_of_product_ids)”。

答案 1 :(得分:0)

在核心代码中搜索:

grep '>addStoreFilter' app/code -rsn 

并观察现有代码中的用法:

Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->addStoreFilter(Mage::app()->getStore()->getId());

答案 2 :(得分:0)

好吧,我认为这样做有效,没有经过太多测试,但似乎已经完成了诀窍。您需要首先获取商店根类别ID,然后加入一些字段,以便您可以访问产品“category_id”,然后使用以下内容进行过滤:

$_rootcatID = Mage::app()->getStore()->getRootCategoryId();

$_testproductCollection = Mage::getResourceModel('catalog/product_collection')
->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left')
->addAttributeToFilter('category_id', array('in' => $_rootcatID))
->addAttributeToSelect('*');
$_testproductCollection->load();

foreach($_testproductCollection as $_testproduct){ 
    echo $this->htmlEscape($_testproduct->getName())."<br/>"; 
};