回答:
OK、それらを調べてみましょう。最初の違いは、addFilter()
より一般的であり、データベース固有ではないということです。またVarien_Directory_Collection
、ファイル名でフィルタリングするためにも使用されます。しかし、この答えのために私は集中するつもりですVarien_Data_Collection_Db
。
これらのメソッドには異なるaddFilter
柔軟性がありますが、柔軟性が低いと思われますが、次のような利点もあることがわかります。
/**
* Add field filter to collection
*
* @see self::_getConditionSql for $condition
*
* @param string|array $field
* @param null|string|array $condition
*
* @return Mage_Eav_Model_Entity_Collection_Abstract
*/
public function addFieldToFilter($field, $condition = null)
addFieldToFilter()は、条件の配列を持つフィールドの配列、または単一の条件を持つ単一のフィールドを取ることができます。
addFieldToFilter('field', 'value')
結果: field=value
addFieldToFilter(['field1', 'field2'], ['value1', 'value2']);
結果: field1=value1 OR field2=value2
各条件は次のとおりです。
'value1'
と'value2'
上記)[ operator => value ]
Zend_Db_Expr
オブジェクトこれ、特に「演算子=>値」の構文は次のコードに記載されていますVarien_Db_Adapter_Pdo_Mysql::prepareSqlCondition()
-これを覚えておいてください、私はかなり頻繁にそれらを調べます:
* If $condition integer or string - exact value will be filtered ('eq' condition)
*
* If $condition is array - one of the following structures is expected:
* - array("from" => $fromValue, "to" => $toValue)
* - array("eq" => $equalValue)
* - array("neq" => $notEqualValue)
* - array("like" => $likeValue)
* - array("in" => array($inValues))
* - array("nin" => array($notInValues))
* - array("notnull" => $valueIsNotNull)
* - array("null" => $valueIsNull)
* - array("moreq" => $moreOrEqualValue)
* - array("gt" => $greaterValue)
* - array("lt" => $lessValue)
* - array("gteq" => $greaterOrEqualValue)
* - array("lteq" => $lessOrEqualValue)
* - array("finset" => $valueInSet)
* - array("regexp" => $regularExpression)
* - array("seq" => $stringValue)
* - array("sneq" => $stringValue)
*
* If non matched - sequential array is expected and OR conditions
* will be built using above mentioned structure
from
/ to
演算子には追加のドキュメント化されていない機能があります。
['from' => $dateFrom, 'to' => $dateTo, 'date' => true]
$dateFrom
$dateTo
Varien_Date::formatDate()
<=
またはの>=
いずれかを比較するだけの場合は、'from'
またはのいずれかを省略できます'to'
。'datetime' => true
は、1日だけでなく、時刻も含むように機能することになっていますが、Varien_Db_Adapter_Pdo_Mysql :: _ prepareSqlDateCondition()($includeTimestamp
パラメーターが欠落している)にはバグがあり、これはdatetime
と同じように動作しdate
ます。両方とも時間が含まれます。あなたは日付だけで比較する必要があるのであれば、追加00:00:00
のfrom
日付と23:59:59
しto
た日付。このメソッドはフィールドマッピングを使用します。フィールドマッピングを具象コレクションクラスで定義して、エイリアスフィールド名を作成できます。製品コレクションの例を次に示します。
protected $_map = array('fields' => array(
'price' => 'price_index.price',
'final_price' => 'price_index.final_price',
'min_price' => 'price_index.min_price',
'max_price' => 'price_index.max_price',
'tier_price' => 'price_index.tier_price',
'special_price' => 'price_index.special_price',
));
/**
* Add collection filter
*s
* @param string $field
* @param string $value
* @param string $type and|or|string
*/
public function addFilter($field, $value, $type = 'and')
addFilter()
単一の値とタイプで単一のフィールドをフィルタリングすることだけを許可します。$type
次のいずれかです。
AND $field=$value
-WHERE句に追加します(もちろん適切な引用符で)"OR $field=$value
-WHERE句に追加(同上)AND $value
-WHERE句に追加します(つまり、$ valueは任意のSQL式にすることができます)_getConditionSql()
に似ました、addFieldToFilter()
。これにより、ほぼ同じように強力になります。ORを組み合わせたさまざまなフィールドに複数のフィルターを追加する機能が欠けています。ではVarien_Data_Collection_Db::_renderFilters()
、あなたそれらがどのように処理されるかを見ることができます。
の利点である重要な違いが1つありaddFilter()
ます。適用するフィルターを収集し、コレクションを読み込む直前にクエリオブジェクトに$this->_filters()
追加するだけZend_Db_Select
です。addFieldToFilter()
一方、クエリオブジェクトをすぐに操作します。
これにより、既に追加されているフィルターを操作または削除できます。Varienコレクションにはインターフェースがありません。これをカスタムコレクションに実装する必要があります。_renderFiltersBefore()
オーバーライドできるフックメソッドがあります。
Magentoコレクションには、以下の2つのフィルタリング方法があります。
- Varien_Data_Collection_Db :: addFieldToFilter
addFieldToFilter($ field、$ condition = null)
の最初のパラメーターaddFieldToFilter
は、フィルター処理する属性です。2番目は、探している値です。sku
valueのフィルターを追加していますn2610
。
2番目のパラメーターを使用して、実行するフィルタリングのタイプを指定することもできます。これは、物事が少し複雑になる場所であり、もう少し詳しく説明する価値があります。
したがって、デフォルトでは、次の
$collection_of_products->addFieldToFilter('sku','n2610');
(本質的に)と同等
WHERE sku = "n2610"
自分で見てください。以下を実行する
public function testAction()
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku','n2610')
->getSelect());
}
もたらすだろう
SELECT `e`.* FROM `catalog_product_entity` AS `e` WHERE (e.sku = 'n2610')'
EAV属性を使用している場合、これはすぐに複雑になります。属性を追加する
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('meta_title','my title')
->getSelect()
);
クエリはひどくなります。
SELECT `e`.*, IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) AS `meta_title`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_varchar` AS `_table_meta_title_default`
ON (_table_meta_title_default.entity_id = e.entity_id) AND (_table_meta_title_default.attribute_id='103')
AND _table_meta_title_default.store_id=0
LEFT JOIN `catalog_product_entity_varchar` AS `_table_meta_title`
ON (_table_meta_title.entity_id = e.entity_id) AND (_table_meta_title.attribute_id='103')
AND (_table_meta_title.store_id='1')
WHERE (IF(_table_meta_title.value_id>0, _table_meta_title.value, _table_meta_title_default.value) = 'my title')
要点を説明するのではなく、期限に間に合うようにSQLについて考えすぎないようにしてください。
他の比較演算子「クエリごとに等しい以外のものが必要な場合はどうすればよいでしょうか?」等しくない、より大きい、より小さいなど。addFieldToFilterメソッドの2番目のパラメーターでも同様に説明します。文字列を渡す代わりに、単一要素の配列を渡す代替構文をサポートしています。
この配列のキーは、作成する比較のタイプです。そのキーに関連付けられている値は、フィルター処理する値です。上記のフィルターをやり直しましょうが、この明示的な構文で
public function testAction()
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku',array('eq'=>'n2610'))
->getSelect()
);
}
フィルターを呼び出す
addFieldToFilter('sku',array('eq'=>'n2610'))
ご覧のとおり、2番目のパラメーターはPHP配列です。そのキーはeqで、equalsを表します。このキーの値はn2610であり、これはフィルタリング対象の値です。
Magentoには、フィルターのようなこれらの英語の言語が多数あり、聴衆の古いperl開発者に思い出の涙(そしておそらく痛み)をもたらします。
以下は、すべてのフィルターと同等のSQLの例です。
array("eq"=>'n2610')
WHERE (e.sku = 'n2610')
array("neq"=>'n2610')
WHERE (e.sku != 'n2610')
array("like"=>'n2610')
WHERE (e.sku like 'n2610')
array("nlike"=>'n2610')
WHERE (e.sku not like 'n2610')
array("is"=>'n2610')
WHERE (e.sku is 'n2610')
array("in"=>array('n2610'))
WHERE (e.sku in ('n2610'))
array("nin"=>array('n2610'))
WHERE (e.sku not in ('n2610'))
array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)
array("null"=>'n2610')
WHERE (e.sku is NULL)
array("gt"=>'n2610')
WHERE (e.sku > 'n2610')
array("lt"=>'n2610')
WHERE (e.sku < 'n2610')
array("gteq"=>'n2610')
WHERE (e.sku >= 'n2610')
array("moreq"=>'n2610') //a weird, second way to do greater than equal
WHERE (e.sku >= 'n2610')
array("lteq"=>'n2610')
WHERE (e.sku <= 'n2610')
array("finset"=>array('n2610'))
WHERE (find_in_set('n2610',e.sku))
array('from'=>'10','to'=>'20')
WHERE e.sku >= '10' and e.sku <= '20'
これらのほとんどは自明ですが、いくつかは特別なコールアウトに値します
in、nin、find_in_set inおよびnin条件を使用すると、値の配列を渡すことができます。つまり、フィルター配列の値部分自体が配列になることが許可されています。
array("in"=>array('n2610','ABC123')
WHERE (e.sku in ('n2610','ABC123'))
notnull、nullキーワードNULLは、ほとんどの種類のSQLで特別です。通常、標準の等号(=)演算子ではうまく動作しません。フィルタータイプとしてnotnullまたはnullを指定すると、渡す値を無視して、NULL比較の正しい構文が取得されます。
array("notnull"=>'n2610')
WHERE (e.sku is NOT NULL)
from-to filterこれは、標準ルールを破る別の特別な形式です。単一の要素配列の代わりに、2つの要素配列を指定します。一方の要素にはキーがあり、もう一方の要素にはキーがあります。キーが示すように、このフィルターにより、大なり記号よりも小さい記号を心配することなく、開始/終了範囲を構築できます。
public function testAction
{
var_dump(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('price',array('from'=>'10','to'=>'20'))
->getSelect()
);
}
上記の収量
WHERE (_table_price.value >= '10' and _table_price.value <= '20')'
ANDまたはOR、またはそのORとANDですか?最後に、ブール演算子について説明します。1つの属性のみでフィルタリングを行うのはまれな瞬間です。幸いなことに、Magentoのコレクションは私たちをカバーしてくれました。addFieldToFilterへの複数の呼び出しを連結して、多くの「AND」クエリを取得できます。
function testAction()
{
echo(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku',array('like'=>'a%'))
->addFieldToFilter('sku',array('like'=>'b%'))
->getSelect()
);
}
上記のように複数の呼び出しを連結することにより、次のようなwhere句を生成します
WHERE (e.sku like 'a%') AND (e.sku like 'b%')
手を挙げたばかりの人には、はい、上の例は常に0レコードを返します。skuは、aとaの両方で始めることはできません。ここでおそらく必要なのはORクエリです。これにより、addFieldToFilterの2番目のパラメーターの別の混乱する側面に至ります。
ORクエリを作成する場合は、2番目のパラメーターとしてフィルター配列の配列を渡す必要があります。個々のフィルター配列を変数に割り当てるのが最善だと思います
public function testAction()
{
$filter_a = array('like'=>'a%');
$filter_b = array('like'=>'b%');
}
そして、すべてのフィルター変数の配列を割り当てます
public function testAction()
{
$filter_a = array('like'=>'a%');
$filter_b = array('like'=>'b%');
echo(
(string)
Mage::getModel('catalog/product')
->getCollection()
->addFieldToFilter('sku',array($filter_a,$filter_b))
->getSelect()
);
}
明示的であるために、前述のフィルター配列の配列を示します。
array($filter_a,$filter_b)
これにより、次のようなWHERE句が得られます。
WHERE (((e.sku like 'a%') or (e.sku like 'b%')))
- Varien_Data_Collection :: addFilter
addFilter($field, $value, $type = 'and')
addFilter()
単一の値とタイプで単一のフィールドのみをフィルタリングできます。$type
次のいずれかです。
addFilter
ありattributes
ますか?