Saring koleksi produk berdasarkan atribut tidak rata


14

Saya melakukan hal berikut:

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

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

my_attribute tidak ada dalam tabel datar, tetapi tabel datar diaktifkan.

Saya terus mendapatkan koleksi lengkapnya.

Alasannya tampaknya ada di \Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect:

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

Tidak $this->getEntity()adalah contoh Mage_Catalog_Model_Resource_Product_Flatyang mengambil bidang datar - dan jika tidak ada yang ditemukan, hanya mengembalikan nol.

Apa cara bersih untuk menambahkan atribut non-flat ke filter koleksi?

Dalam kasus saya itu tidak masuk akal, untuk menambahkan atribut ke tabel datar.


Hai pak APAKAH ANDA BAIK DIMAKSUDKAN untuk menyelesaikan Kebingungan ?? WAT yang dimaksud dengan non-flat attribute? Terima kasih. Dan jangan membuat magento membingungkan. Ini sudah membingungkan
Pratik

Saya berbicara tentang atribut yang tidak ada dalam indeks datar. Ini adalah mereka yang "Digunakan dalam Daftar Produk" diatur ke "Tidak".
Alex

Jawaban:


18

Anda bisa bergabung dengan tabel yang diperlukan sendiri.

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

Anda mungkin ingin bergabung dengan store_id juga.


Saya pikir saya masih memiliki masalah sehingga saya tidak mendapatkan produk dari semua toko. (setiap kali saya awalnya tidak melihat masalah ini di pertanyaan saya). Sepertinya saya ingin sepenuhnya menonaktifkan indeks datar.
Alex

Jika Anda membutuhkan semua produk, maka tabel datar tidak akan menjadi teman Anda, ya.
Matthias Zeis

Saya kira Anda mungkin ingin mengubah pertanyaan Anda atau menerima jawaban saya (yang berfungsi untuk pertanyaan asli), kalau begitu.
Matthias Zeis

awasome .. concept
Amit Bera

15

Retasan (CE 1.6.2.0+) adalah untuk lulus kondisi sebagai array dan percaya atau tidak ini berfungsi sebagaimana dimaksud:

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

Adakah petunjuk mengapa itu berhasil?
Alex

3
Ini berfungsi karena untuk koleksi EAV addFieldToFileradalah pembungkus untuk addAttributeToFilterdan ini memiliki opsi untuk melewatkan atribut sebagai array:if (is_array($attribute)) { $sqlArr = array(); foreach ($attribute as $condition) { $sqlArr[] = $this->_getAttributeConditionSql($condition['attribute'], $condition, $joinType); } $conditionSql = '('.implode(') OR (', $sqlArr).')'; }
Marius

@Marius, apakah itu berarti ini bukan peretasan? : P Bisakah saya merasa senang menggunakannya?
Erfan

3
@Erfan. itu bukan hack. itu adalah fitur.
Marius

Manis. Masih agak aneh implementasi tabel produk (eav / flat) tidak diabstraksi untuk hal-hal sederhana seperti memfilter koleksi. Apakah ini berarti saya selalu perlu menggunakan addFieldToFilter daripada addAttributeToFilter dalam kode saya, karena saya tidak akan tahu apakah itu menggunakan eav atau flat? Apa gunanya addAttributeToFilter?
Erfan

6

Alasan jawaban ColinM ini bekerja adalah karena kode di app/code/core/Mage/Catalog/Model/Resource/Product/Collection.php's addAttributeToFiltermetode. Jika Anda menggunakan format array ini, itu tidak memanggil addAttributeToSelect. Dalam mode flat, addAttributeToSelectgagal secara diam-diam jika atribut tidak ada di tabel rata.

(di bawah ini adalah hash dari jawaban saya di /programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620 - Saya tidak yakin apa etiket untuk itu tetapi tahu saya akan merasa terbantu)

Saya menginginkan solusi "bersih" untuk memilih dan memfilter koleksi mode-datar pada atribut non-datar, yang:

  • tidak memerlukan atribut untuk memiliki pengaturan khusus di admin (mungkin ditambahkan oleh pengguna, atau disembunyikan di ujung depan)
  • berfungsi untuk mode flat dan non-flat

Saya menggunakan koleksi produk terkait, tetapi ini berlaku untuk setiap koleksi EAV.

Kode gagal:

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

Dalam mode flat, kode di atas diam-diam gagal memilih atau memfilter atribut jika kebetulan tidak ada dalam tabel datar.

Menambahkan ke pilih:

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

The joinAttributeMetode menambahkan bergabung untuk query untuk atribut tertentu yang diminta. Ini masih berfungsi ketika atribut sudah ada di tabel rata, tetapi akan sedikit kurang efisien daripada hanya menggunakan tabel datar.

Saya telah menggunakan leftgabungan di sana, untuk memastikan bahwa ia mengambil produk jika my_custom_attributetidak diatur pada produk-produk itu. Ubah itu untuk innerjika Anda hanya tertarik pada baris my_custom_attributeyang diatur.

Menambahkan ke filter (sesuai ColinM di atas):

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

Kode di atas akan menambahkannya ke pilih serta mematuhi filter Anda.

(diuji pada CE 1.6.2.0)


4

Dalam Mage_Rssmodul mereka menggunakan metode hacky untuk menonaktifkan tabel datar. Mereka menggunakan fakta, bahwa tabel datar selalu mati di toko admin dan hanya meniru toko admin.

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

Setelah memulai emulasi Anda harus mengatur ulang dengan emulationModel->stopEnvironmentEmulation()


Di mana jawaban ini 3 hari yang lalu? ; _;
sg3

Disini? Sejak 20 Maret.
Alex

1

ketika Anda membuat atribut itu harus di tingkat Global dan dapat difilter. Dengan cara ini akan dapat digunakan dalam navigasi layared. Juga akan memerlukan atribut menjadi dropdown atau multiselect. Saya pribadi akan menyarankan untuk tidak mengubah file inti agar sesuai dengan kebutuhan Anda dalam hal ini


Saya tidak ingin atribut di filter frontend - Saya hanya ingin melakukan pemfilteran koleksi untuk penggunaan internal.
Alex
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.