กรองการรวบรวมผลิตภัณฑ์ตามคุณลักษณะที่ไม่ใช่แบบแบน


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

ไม่มี$this->getEntity()เป็นอินสแตนซ์Mage_Catalog_Model_Resource_Product_Flatที่ดึงฟิลด์แบน - และหากไม่พบจะส่งคืนค่าว่าง

วิธีที่สะอาดในการเพิ่มแอตทริบิวต์ที่ไม่ใช่แบบแบนไปยังตัวกรองการเก็บคืออะไร?

ในกรณีของฉันมันไม่มีเหตุผลที่จะเพิ่มคุณลักษณะไปยังตารางแบน


สวัสดีครับคุณเป็นคนประเภทไหนที่ต้องการแก้ไขความสับสน? วัดมีค่าเฉลี่ยnon-flat attributeอะไร ขอบคุณ. และอย่าทำให้วีโอไอพีสับสนเพราะมันสับสนอยู่แล้ว
Pratik

ฉันกำลังพูดถึงคุณลักษณะที่ไม่ได้อยู่ในดัชนีเรียบ สิ่งเหล่านี้คือ "ที่ใช้ในรายการผลิตภัณฑ์" ตั้งค่าเป็น "ไม่"
อเล็กซ์

คำตอบ:


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

แนวคิดสุดยอดมาก
Amit Bera

15

แฮ็ค (CE 1.6.2.0+) จะต้องผ่านเงื่อนไขในฐานะอาร์เรย์และเชื่อหรือไม่ว่าทำงานได้ตามที่ต้องการ:

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

เบาะแสใดที่ว่าทำไมถึงใช้งานได้?
อเล็กซ์

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
@Erfan ไม่ใช่แฮ็ค มันเป็นคุณสมบัติ
Marius

หวาน. ยังคงแปลกที่การใช้ตารางผลิตภัณฑ์ (eav / flat) ไม่ได้ถูกแยกออกไปสำหรับสิ่งต่าง ๆ ที่ง่ายเหมือนกับการกรองคอลเลกชัน นี่หมายความว่าฉันต้องใช้ addFieldToFilter แทน addAttributeToFilter ในรหัสของฉันเพราะฉันไม่รู้ว่าใช้ eav หรือ flat หรือไม่ จุดของ addAttributeToFilter คืออะไรต่อไป
Erfan

6

เหตุผลคำตอบ ColinM ทำงานเป็นเพราะรหัสในapp/code/core/Mage/Catalog/Model/Resource/Product/Collection.php'saddAttributeToFilterวิธี หากคุณใช้รูปแบบอาร์เรย์นี้จะไม่เรียก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

ที่นี่? ตั้งแต่ 20 มี.ค.
อเล็กซ์

1

เมื่อคุณสร้างคุณสมบัติมันควรจะอยู่ในระดับโลกและสามารถกรองได้ วิธีนี้จะสามารถใช้งานได้ในการนำทางแบบฝัง นอกจากนี้ยังจำเป็นต้องมีแอตทริบิวต์เพื่อเป็นแบบเลื่อนลงหรือเลือกหลายรายการ ส่วนตัวผมขอแนะนำให้เปลี่ยนไฟล์หลักเพื่อให้เหมาะกับความต้องการของคุณในกรณีนี้


ฉันไม่ต้องการคุณลักษณะในตัวกรองส่วนหน้า - ฉันแค่ต้องการกรองคอลเลกชันสำหรับใช้ภายใน
Alex
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.