Lọc bộ sưu tập sản phẩm theo thuộc tính không phẳng


14

Tôi đang làm như sau:

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

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

my_attribute không nằm trong các bảng phẳng, nhưng các bảng phẳng được bật.

Tôi tiếp tục nhận được bộ sưu tập đầy đủ.

Lý do dường như là trong \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

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

Không có $this->getEntity()trường hợp Mage_Catalog_Model_Resource_Product_Flatnào tìm nạp các trường phẳng - và nếu không tìm thấy, chỉ trả về null.

Cách sạch để thêm thuộc tính không phẳng vào bộ lọc bộ sưu tập là gì?

Trong trường hợp của tôi, nó không có nghĩa, để thêm thuộc tính vào bảng phẳng.


Chào ngài LÀ BẠN CÓ THỂ giải quyết nhầm lẫn ?? Bình có nghĩa là non-flat attributegì? Cảm ơn .và đừng làm cho magento trở nên khó hiểu. Điều đó thật khó hiểu
Pratik

Tôi đang nói về các thuộc tính không có trong chỉ mục phẳng. Đây là những cái có "Được sử dụng trong Danh sách sản phẩm" được đặt thành "Không".
Alex

Câu trả lời:


18

Bạn có thể tham gia bảng cần thiết cho mình.

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

Bạn cũng có thể muốn tham gia bởi store_id.


Tôi nghĩ rằng tôi vẫn sẽ gặp vấn đề là tôi không nhận được sản phẩm của tất cả các cửa hàng. (bất cứ khi nào ban đầu tôi không thấy vấn đề này trong câu hỏi của mình). Có vẻ như tôi muốn vô hiệu hóa hoàn toàn các chỉ số phẳng.
Alex

Nếu bạn cần tất cả các sản phẩm, thì bàn phẳng sẽ không phải là bạn của bạn, vâng.
Matthias Zeis

Tôi đoán bạn có thể muốn sửa đổi câu hỏi của bạn hoặc chấp nhận câu trả lời của tôi (hoạt động cho câu hỏi ban đầu), sau đó.
Matthias Zeis

awasome .. khái niệm
Amit Bera

15

Một hack (CE 1.6.2.0+) là để vượt qua điều kiện dưới dạng một mảng và tin rằng nó hoặc không hoạt động như dự định:

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

Bất kỳ manh mối tại sao điều đó làm việc?
Alex

3
Nó hoạt động vì bộ sưu tập eav addFieldToFilerlà một trình bao bọc addAttributeToFiltervà điều này có một tùy chọn để chuyển thuộc tính dưới dạng một mảng:if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; }
Marius

@Marius, điều đó có nghĩa là nó không phải là hack? : P Tôi có thể cảm thấy tốt khi sử dụng nó không?
Erfan

3
@Erfan. Nó không phải là hack. đó là một tính năng.
Marius

Ngọt. Việc triển khai bảng sản phẩm (eav / Flat) vẫn chưa được thực hiện đối với những thứ đơn giản như lọc một bộ sưu tập. Điều này có nghĩa là tôi luôn cần sử dụng addFieldToFilter thay vì addAttributionToFilter trong mã của mình, vì tôi sẽ không biết nếu nó sử dụng eav hay phẳng? Điểm của addAttributionToFilter là gì?
Erfan

6

Lý do câu trả lời ColinM của công trình là do các mã trong app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php's addAttributeToFilterphương pháp. Nếu bạn sử dụng định dạng mảng này, nó không gọi addAttributeToSelect. Trong chế độ phẳng, addAttributeToSelectâm thầm thất bại nếu thuộc tính không nằm trong bảng phẳng.

(dưới đây là một tái băm của câu trả lời của tôi trên /programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Tôi không chắc chắn về nghi thức đó là gì nhưng biết rằng tôi sẽ thấy nó hữu ích)

Tôi muốn một giải pháp "sạch" cho bộ sưu tập chế độ phẳng chọn và lọc trên các thuộc tính không phẳng, trong đó:

  • không yêu cầu thuộc tính phải có cài đặt cụ thể trong quản trị viên (có thể được thêm bởi người dùng hoặc ẩn ở mặt trước)
  • hoạt động cho cả chế độ phẳng và không phẳng

Tôi đã sử dụng bộ sưu tập sản phẩm liên quan, nhưng điều này áp dụng cho bất kỳ bộ sưu tập EAV nào.

Mã không thành công:

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

Trong chế độ phẳng, đoạn mã trên âm thầm không thể chọn hoặc lọc trên thuộc tính nếu nó không nằm trong bảng phẳng.

Thêm vào lựa chọn:

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

Các joinAttributephương pháp thêm một tham gia vào truy vấn cho thuộc tính cụ thể được yêu cầu. Nó vẫn hoạt động khi thuộc tính đã có trong bảng phẳng, nhưng sẽ kém hiệu quả hơn một chút so với sử dụng hoàn toàn bảng phẳng.

Tôi đã sử dụng một lefttham gia ở đó, để đảm bảo rằng nó tìm nạp các sản phẩm nếu my_custom_attributekhông được đặt trên các sản phẩm đó. Thay đổi điều đó innernếu bạn chỉ quan tâm đến các hàng my_custom_attributeđược đặt.

Thêm vào bộ lọc (theo ColinM ở trên):

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

Đoạn mã trên sẽ thêm nó vào phần chọn cũng như tuân theo bộ lọc của bạn.

(được thử nghiệm trong CE 1.6.2.0)


4

Trong Mage_Rssmô-đun, họ đã sử dụng phương pháp hacky để vô hiệu hóa các bảng phẳng. Họ sử dụng thực tế là các bàn phẳng luôn tắt trong cửa hàng quản trị và vì vậy chỉ cần mô phỏng cửa hàng quản trị.

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

Sau khi bắt đầu mô phỏng, bạn nên thiết lập lại với emulationModel->stopEnvironmentEmulation()


Câu trả lời này ở đâu 3 ngày trước? ; _;
sg3s

Ngay tại đây? Kể từ ngày 20 tháng 3
Alex

1

Khi bạn tạo thuộc tính, nó phải ở cấp Toàn cầu và có thể lọc. Bằng cách này, nó sẽ có thể được sử dụng trong điều hướng layared. Ngoài ra, nó sẽ yêu cầu thuộc tính là một danh sách thả xuống hoặc đa lựa chọn. Cá nhân tôi sẽ tư vấn chống thay đổi các tập tin cốt lõi để phù hợp với nhu cầu của bạn trong trường hợp này


Tôi không muốn thuộc tính trong bộ lọc frontend - Tôi chỉ đơn giản muốn thực hiện lọc bộ sưu tập để sử dụng nội bộ.
Alex
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.