Magento addFieldToFilter:两个字段,匹配OR,而不是AND
在过去的几个小时里,我一直被困在这里。 我通过在/lib/Varien/Data/Collection/Db.php
中/lib/Varien/Data/Collection/Db.php
了几行/lib/Varien/Data/Collection/Db.php
,但是我宁愿使用合适的解决scheme,而不使用我的核心。
我需要做的就是获得一个集合,并通过两个或多个字段进行过滤。 说, customer_firstname
和remote_ip
。 这是我的( Db.php
没有黑客)代码:
$collection = Mage::getModel('sales/order')->getCollection()-> addAttributeToSelect("*")-> addFieldToFilter(array(array('remote_ip', array('eq'=>'127.0.0.1')), array('customer_firstname', array('eq'=>'gabe'))), array('eq'=>array(1,2,3)));
与股票Db.php
,我试过这个:(从http://magentoexpert.blogspot.com/2009/12/retrieve-products-with-specific.html采取样本)
$collection->addFieldToFilter(array( array('name'=>'orig_price','eq'=>'Widget A'), array('name'=>'orig_price','eq'=>'Widget B'), ));
但是,这给了我这个错误:
Warning: Illegal offset type in isset or empty in magento/lib/Varien/Data/Collection/Db.php on line 369
如果我用try / catch包装它,然后移动到_getConditionSql()并给出这个错误:
Warning: Invalid argument supplied for foreach() in magento/lib/Varien/Data/Collection/Db.php on line 412
有没有人有这样做的工作,function代码? 我正在运行Magento 1.9(企业版)。 谢谢!
我有另外一种方法来在现场添加一个or
一个条件:
->addFieldToFilter( array('title', 'content'), array( array('like'=>'%$titlesearchtext%'), array('like'=>'%$contentsearchtext%') ) )
OR条件可以像这样产生:
$collection->addFieldToFilter( array('field_1', 'field_2', 'field_3'), // columns array( // conditions array( // conditions for field_1 array('in' => array('text_1', 'text_2', 'text_3')), array('like' => '%text') ), array('eq' => 'exact'), // condition for field 2 array('in' => array('val_1', 'val_2')) // condition for field 3 ) );
这将生成一个SQL WHERE条件如下所示:
... WHERE ( (field_1 IN ('text_1', 'text_2', 'text_3') OR field_1 LIKE '%text') OR (field_2 = 'exact') OR (field_3 IN ('val_1', 'val_2')) )
每个嵌套数组(<condition>)为OR条件生成另一组括号。
我也试图得到field1 = 'a' OR field2 = 'b'
你的代码不适合我。
这是我的解决scheme
$results = Mage::getModel('xyz/abc')->getCollection(); $results->addFieldToSelect('name'); $results->addFieldToSelect('keywords'); $results->addOrder('name','ASC'); $results->setPageSize(5); $results->getSelect()->where("keywords like '%foo%' or additional_keywords like '%bar%'"); $results->load(); echo json_encode($results->toArray());
它给了我
SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%'
。
这可能不是“magento的方式”,但我坚持了5个小时。
希望它会有所帮助
这是我在Enterprise 1.11中的解决scheme(应该在CE 1.6中工作):
$collection->addFieldToFilter('max_item_count', array( array('gteq' => 10), array('null' => true), ) ) ->addFieldToFilter('max_item_price', array( array('gteq' => 9.99), array('null' => true), ) ) ->addFieldToFilter('max_item_weight', array( array('gteq' => 1.5), array('null' => true), ) );
这导致了这个SQL:
SELECT `main_table`.* FROM `shipping_method_entity` AS `main_table` WHERE (((max_item_count >= 10) OR (max_item_count IS NULL))) AND (((max_item_price >= 9.99) OR (max_item_price IS NULL))) AND (((max_item_weight >= 1.5) OR (max_item_weight IS NULL)))
要按多个属性进行过滤,请使用类似于
//for AND $collection = Mage::getModel('sales/order')->getCollection() ->addAttributeToSelect('*') ->addFieldToFilter('my_field1', 'my_value1') ->addFieldToFilter('my_field2', 'my_value2'); echo $collection->getSelect()->__toString(); //for OR - please note 'attribute' is the key name and must remain the same, only replace //the value (my_field1, my_field2) with your attribute name $collection = Mage::getModel('sales/order')->getCollection() ->addAttributeToSelect('*') ->addFieldToFilter( array( array('attribute'=>'my_field1','eq'=>'my_value1'), array('attribute'=>'my_field2', 'eq'=>'my_value2') ) );
有关更多信息,请参阅: http : //docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql
谢谢安达,你的post是一个很好的帮助! 然而,OR语句对我来说并不是非常有用,而且我得到了一个错误: getCollection()“为foreach提供了无效的参数” 。
所以这就是我所结束的(在这种情况下注意属性被指定3次而不是2):
$collection->addFieldToFilter('attribute', array( array('attribute'=>'my_field1','eq'=>'my_value1'), array('attribute'=>'my_field2','eq'=>'my_value2') ));
addFieldToFilter首先需要一个字段,然后条件 – > 链接。
这里有一些混乱,但让我试着澄清一下事情:
让我们说你想要的SQL看起来像这样:
SELECT `main_table`.*, `main_table`.`email` AS `invitation_email`, `main_table`.`group_id` AS `invitee_group_id` FROM `enterprise_invitation` AS `main_table` WHERE ( (status = 'new') OR (customer_id = '1234') )
为了实现这一点,你的collections需要像这样格式化:
$collection = Mage::getModel('enterprise_invitation/invitation')->getCollection(); $collection->addFieldToFilter(array('status', 'customer_id'), array( array('status','eq'=>'new'), array('customer_id', 'eq'=>'1234') ));
现在看看这个样子是什么样的,你总是可以回应这个使用的查询
echo $collection->getSelect()->__toString();
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() ); }
结果:
WHERE (((e.sku like 'a%') or (e.sku like 'b%')))
来源: http : //alanstorm.com/magento_collections
要创build简单的OR条件进行收集,请使用以下格式:
$orders = Mage::getModel('sales/order')->getResourceCollection(); $orders->addFieldToFilter( 'status', array( 'processing', 'pending', ) );
这将产生像这样的SQL:
WHERE (((`status` = 'processing') OR (`status` = 'pending')))
这是真正的magento方式:
$collection=Mage::getModel('sales/order') ->getCollection() ->addFieldToFilter( array( 'customer_firstname',//attribute_1 with key 0 'remote_ip',//attribute_2 with key 1 ), array( array('eq'=>'gabe'),//condition for attribute_1 with key 0 array('eq'=>'127.0.0.1'),//condition for attribute_2 ) ) );