非フラット属性による製品コレクションのフィルター


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フラットフィールドを取得するインスタンスです。見つからない場合は、nullを返します。

コレクションフィルターに非フラット属性を追加するクリーンな方法は何ですか?

私の場合、フラットテーブルに属性を追加することは意味がありません。


こんにちは先生混乱を解決したいと思いますか?WATとはnon-flat attribute?ありがとう。
そして、

フラットインデックスにない属性について説明しています。これらは、「製品リストで使用」が「いいえ」に設定されているものです。
アレックス14年

回答:


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で参加することもできます。


私はまだすべての店の製品を入手できないという問題があると思います。(質問でこの問題が最初に見られなかったときはいつでも)。フラットインデックスを完全に無効にしたいようです。
アレックス

すべての製品が必要な場合、フラットテーブルはあなたの友達ではありません。
マティアスツァイス

その場合は、質問を変更するか、私の回答(元の質問で有効)を受け入れてください。
マティアスツァイス

awasome ..コンセプト
アミットベラ

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、それはハックではないということですか?:P私はそれを使うことについて気分がいいですか?
エルファン14

3
@Erfan。ハックではありません。それは機能です。
マリウス

甘い。コレクションをフィルタリングするのと同じくらい単純なことのために、製品テーブルの実装(eav / flat)が抽象化されていないことは、まだ少し奇妙です。これは、コードでaddAttributeToFilterの代わりにaddFieldToFilterを常に使用する必要があることを意味します。eavを使用しているかフラットを使用しているかわからないからです。とにかくaddAttributeToFilterのポイントは何ですか?
エルファン14

6

ColinMの答えが機能する理由は、app/code/core/Mage/Catalog/Model/Resource/Product/Collection.phpaddAttributeToFilterメソッドのコードによるものです。この配列形式を使用する場合、呼び出しませんaddAttributeToSelect。フラットモードでaddAttributeToSelectは、属性がフラットテーブルにない場合、サイレントモードで失敗します。

(以下は/programming/6271284/can-i-add-other-attributes-to-magentos-flat-product-catalog-table/17021620の私の答えの再ハッシュですです-私はそのためのエチケットが何であるかわからないが、私はそれが役立つと思うだろうことを知っている)

私は、フラットモードコレクションを選択し、非フラット属性でフィルタリングするための「クリーンな」ソリューションが必要でした。

  • adminで属性を特定の設定にする必要はありません(ユーザーによって追加されるか、フロントエンドで非表示になる場合があります)
  • フラットモードと非フラットモードの両方で動作します

関連する製品コレクションを使用しましたが、これはすべての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
アレックス

1

属性を作成するときは、グローバルレベルでフィルタリング可能でなければなりません。これにより、レイヤー化されたナビゲーションで使用できるようになります。また、属性はドロップダウンまたは複数選択である必要があります。この場合、ニーズに合わせてコアファイルを変更しないように個人的にアドバイスします。


フロントエンドフィルターに属性が必要ない-単に内部使用のためにコレクションフィルターを実行したい。
アレックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.