평평하지 않은 속성으로 제품 수집 필터링 ->addAttributeToFilter(‘my_attribute’, 1); my_attribute 플랫 테이블에

나는 다음을하고있다 :

$productCollection = Mage::getModel('catalog/product')
    ->getCollection();

$productCollection
    ->addAttributeToFilter('my_attribute', 1);

my_attribute 플랫 테이블에 없지만 플랫 테이블이 사용됩니다.

나는 전체 컬렉션을 계속 받고 있습니다.

이유는 다음과 \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect같습니다.

$columns = $this->getEntity()->getAttributeForSelect($attributeCode);

No $this->getEntity()Mage_Catalog_Model_Resource_Product_Flat플랫 필드를 가져 오는 인스턴스입니다. 이 필드가 없으면 null 만 반환합니다.

플랫 필터가 아닌 속성을 컬렉션 필터에 추가하는 확실한 방법은 무엇입니까?

필자의 경우 플랫 테이블에 속성을 추가하는 것이 의미가 없습니다.



답변

필요한 테이블을 직접 참여시킬 수 있습니다.

$productCollection = Mage::getModel('catalog/product')
->getCollection();

$table = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getBackend()->getTable();
$attributeId = Mage::getSingleton('eav/config')->getAttribute('catalog_product', 'my_attribute')->getAttributeId();

$productCollection->getSelect()->join(array('attributeTable' => $table), 'e.entity_id = attributeTable.entity_id', array('my_attribute' => 'attributeTable.value'))
                            ->where("attributeTable.attribute_id = ?", $attributeId)
                            ->where("attributeTable.value = ?", 1);

store_id로 가입하고 싶을 수도 있습니다.


답변

해킹 (CE 1.6.2.0+)은 조건을 배열로 전달하고 이것이 의도 한대로 작동하는지 여부를 믿어야합니다.

$collection->addFieldToFilter(array(array('attribute' => 'my_attribute', 'eq' => 1)));

답변

ColinM의 답변이 작동하는 이유는 app/code/core/Mage/Catalog/Model/Resource/Product/Collection.phpaddAttributeToFilter메소드 코드 때문 입니다. 이 배열 형식을 사용하면을 호출하지 않습니다 addAttributeToSelect. 플랫 모드 addAttributeToSelect에서 속성이 플랫 테이블에 없으면 자동으로 실패합니다.

(아래는 /programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620에 대한 답변의 해시입니다. – 난 에티켓이 무엇인지 잘 모르겠지만 도움이 될 것입니다.)

플랫 모드가 아닌 속성에서 플랫 모드 컬렉션을 선택하고 필터링하기위한 “깨끗한”솔루션이 필요했습니다.

  • 속성에 관리자의 특정 설정이 필요하지 않습니다 (사용자가 추가하거나 프런트 엔드에서 숨길 수 있음)
  • 플랫 모드와 비 플랫 모드 모두에서 작동

관련 제품 컬렉션을 사용했지만 모든 EAV 컬렉션에 적용됩니다.

실패 코드 :

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToSelect( 'my_custom_attribute' )
    ->addAttributeToFilter( 'my_custom_attribute', 3 )
;

플랫 모드에서 위 코드는 플랫 테이블에 없으면 속성을 자동으로 선택하거나 필터링하지 못합니다.

선택에 추가 :

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->joinAttribute( 'my_custom_attribute', 'catalog_product/my_custom_attribute', 'entity_id', null, 'left' )
    ->addAttributeToSelect( 'my_custom_attribute' )
;

그만큼 joinAttribute 메소드는 요청 된 특정 속성에 대한 쿼리에 조인을 추가합니다. 속성이 이미 플랫 테이블에있을 때 여전히 작동하지만 플랫 테이블을 사용하는 것보다 약간 덜 효율적입니다.

left거기 에 조인을 사용하여 my_custom_attribute해당 제품에 설정되어 있지 않은 경우 제품을 가져옵니다 . 설정된 inner행에만 관심이있는 경우 변경하십시오 my_custom_attribute.

필터에 추가 (위의 ColinM에 따라) :

$_product = Mage::getModel('catalog/product')->loadByAttribute( 'sku', 'ABC123' );
$coll = $_product->getTypeInstance()->getAssociatedProductCollection()
    ->addAttributeToFilter( array( array( 'attribute' => 'my_custom_attribute', 'eq' => 3 ) ) )
;

위의 코드는 선택에 추가하고 필터를 준수합니다.

(CE 1.6.2.0에서 테스트)


답변

에서 Mage_Rss모듈 그들은 평면 테이블을 비활성화 할 수 해키 – 방법을 사용했다. 플랫 테이블은 항상 관리자 저장소에서 꺼져 있으므로 관리자 저장소를 에뮬레이트한다는 사실을 사용합니다.

class Mage_Rss_Helper_Data {

[...]

/**
 * Disable using of flat catalog and/or product model to prevent limiting results to single store. Probably won't
 * work inside a controller.
 *
 * @return null
 */
public function disableFlat()
{
    /* @var $flatHelper Mage_Catalog_Helper_Product_Flat */
    $flatHelper = Mage::helper('catalog/product_flat');
    if ($flatHelper->isEnabled()) {
        /* @var $emulationModel Mage_Core_Model_App_Emulation */
        $emulationModel = Mage::getModel('core/app_emulation');
        // Emulate admin environment to disable using flat model - otherwise we won't get global stats
        // for all stores
        $emulationModel->startEnvironmentEmulation(0, Mage_Core_Model_App_Area::AREA_ADMINHTML);
    }
}

에뮬레이션을 시작한 후에는 emulationModel->stopEnvironmentEmulation()


답변

속성을 만들 때 전역 수준에 있고 필터링 가능해야합니다. 이런 식으로 레이아웃 탐색에서 사용할 수 있습니다. 또한 속성이 드롭 다운 또는 다중 선택이어야합니다. 이 경우 귀하의 요구에 맞게 코어 파일을 변경하지 않도록 개인적으로 조언합니다.