평평하지 않은 속성으로 제품 수집 필터링


14

나는 다음을하고있다 :

$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 만 반환합니다.

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

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


안녕하세요 선생님은 혼란을 해결하기 위해 노력하고 있습니까 ?? WAT는 non-flat attribute? 감사합니다. 그리고 magento를 혼동하지 마십시오. 이미 혼란스러워
— Pratik

플랫 인덱스에없는 속성에 대해 이야기하고 있습니다. "제품 목록에 사용됨"이 "아니오"로 설정된 것입니다.
— Alex

답변:


18

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

$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로 가입하고 싶을 수도 있습니다.


나는 여전히 모든 상점의 제품을 얻지 못한다는 문제가 있다고 생각합니다. (내 질문 에이 문제가 원래 보이지 않을 때마다). 평평한 인덱스를 완전히 비활성화하려는 것 같습니다.
— Alex

모든 제품이 필요하다면 평평한 테이블이 친구가 아닙니다.
— Matthias Zeis

그런 다음 질문을 수정하거나 원래 답변에 맞는 내 답변을 수락하고 싶을 것입니다.
— Matthias Zeis

awasome .. concept
— Amit Bera

15

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

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

왜 작동하는지 힌트가 있습니까?
— Alex

3
eav 수집 addFieldToFiler이 래퍼 이기 때문에 작동 addAttributeToFilter하며, 속성을 배열로 전달하는 옵션이 있습니다.if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; }
— Marius

@Marius, 그것은 핵이 아니라는 것을 의미합니까? : P 사용해도 좋을까요?
— Erfan

3
@ 에르 판 해킹이 아닙니다. 기능입니다.
— Marius

단. 제품 테이블 구현 (eav / flat)이 컬렉션을 필터링하는 것만 큼 간단한 것으로 추상화되지 않은 것은 여전히 ​​이상한 일입니다. 이것은 eav 또는 flat을 사용하는지 알 수 없기 때문에 항상 코드에서 addAttributeToFilter 대신 addFieldToFilter를 사용해야한다는 것을 의미합니까? 어쨌든 addAttributeToFilter의 요점은 무엇입니까?
— Erfan

6

ColinM의 답변이 작동하는 이유는 app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php의 addAttributeToFilter메소드 코드 때문 입니다. 이 배열 형식을 사용하면을 호출하지 않습니다 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에서 테스트)


4

에서 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()


이 답변은 3 일 전에 어디에 있었습니까? ; _;
— sg3s

바로 여기에? 3 월 20 일부터.
— Alex

1

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


프론트 엔드 필터에서 속성을 원하지 않습니다. 내부 용으로 수집 필터링을 수행하고 싶습니다.
— Alex
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.