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.

Alex
sumber
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.

Matthias Zeis
sumber
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)));
Kolin
sumber
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)

Johnorourke
sumber
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()

Alex
sumber
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

Sander Mangel
sumber
Saya tidak ingin atribut di filter frontend - Saya hanya ingin melakukan pemfilteran koleksi untuk penggunaan internal.
Alex