php Magento addFieldToFilter:两个字段,匹配为 OR,而不是 AND
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3826474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Magento addFieldToFilter: Two fields, match as OR, not AND
提问by Gabriel H
I've been stuck on this for the last few hours. I got it working by hacking a few lines in /lib/Varien/Data/Collection/Db.php
, but I'd rather use the proper solution and leave my core untouched.
在过去的几个小时里,我一直被困在这个问题上。我通过在/lib/Varien/Data/Collection/Db.php
.
All I need to do is get a collection and filter it by two or more fields. Say, customer_firstname
and remote_ip
. Here's my (disfunctional without hacking Db.php
) code:
我需要做的就是获取一个集合并按两个或多个字段对其进行过滤。说,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)));
With a stock Db.php
, I tried this: (sample taken from http://magentoexpert.blogspot.com/2009/12/retrieve-products-with-specific.html)
有了股票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'),
));
But that gives me this error:
但这给了我这个错误:
Warning: Illegal offset type in isset or empty in magento/lib/Varien/Data/Collection/Db.php on line 369
If I wrap that with a try/catch, then it moves into _getConditionSql() and gives this error:
如果我用 try/catch 包装它,那么它会进入 _getConditionSql() 并给出以下错误:
Warning: Invalid argument supplied for foreach() in magento/lib/Varien/Data/Collection/Db.php on line 412
Does anyone have any working, functional code for doing this? I'm running Magento 1.9 (Enterprise). Thanks!
有没有人有任何工作,功能代码来做到这一点?我正在运行 Magento 1.9(企业)。谢谢!
回答by Riyazkhan
I've got another way to add an or
condition in the field:
我有另一种or
在字段中添加条件的方法:
->addFieldToFilter(
array('title', 'content'),
array(
array('like'=>'%$titlesearchtext%'),
array('like'=>'%$contentsearchtext%')
)
)
回答by CJ Dennis
OR conditions can be generated like this:
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
)
);
This will generate an SQL WHERE condition something like:
这将生成一个 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'))
)
Each nested array(<condition>) generates another set of parentheses for an OR condition.
每个嵌套数组(<condition>) 为 OR 条件生成另一组括号。
回答by user654539
I also tried to get the field1 = 'a' OR field2 = 'b'
我也试图得到 field1 = 'a' OR field2 = 'b'
Your code didn't work for me.
你的代码对我不起作用。
Here is my solution
这是我的解决方案
$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());
It gives me
它给了我
SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%'
.
SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%'
.
It is maybe not the "magento's way" but I was stuck 5 hours on that.
这可能不是“magento 的方式”,但我在这上面被困了 5 个小时。
Hope it will help
希望它会有所帮助
回答by Michael Payne
Here is my solution in Enterprise 1.11 (should work in CE 1.6):
这是我在 Enterprise 1.11 中的解决方案(应该适用于 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),
)
);
Which results in this SQL:
这导致此 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)))
回答by Anda B
To filter by multiple attributes use something like:
要按多个属性过滤,请使用以下内容:
//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')
)
);
For more information check: http://docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql
有关更多信息,请查看:http: //docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql
回答by jazkat
Thanks Anda, your post has been a great help!! However the OR sentence didnt' quite work for me and I was getting an error: getCollection() "invalid argument supplied for foreach".
谢谢安达,你的帖子帮了大忙!!然而,OR 语句对我来说并不完全有效,我收到了一个错误: getCollection() "invalid argument provided for foreach"。
So this is what I ended with (notice the attribute being specified 3 times instead of 2 in this case):
所以这就是我的结尾(注意在这种情况下属性被指定了 3 次而不是 2 次):
$collection->addFieldToFilter('attribute', array(
array('attribute'=>'my_field1','eq'=>'my_value1'),
array('attribute'=>'my_field2','eq'=>'my_value2') ));
addFieldToFilter first requires a field and then condition -> link.
addFieldToFilter 首先需要一个字段,然后是条件 ->链接。
回答by phpCodeNinja
There is a bit of confusion going on here, but let me try to clarify things:
这里有一些混乱,但让我试着澄清一下:
Lets say you wanted sql that looked something like:
假设您想要看起来像这样的 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')
)
In order to achieve this, your collection needs to be formatted like this:
为了实现这一点,您的集合需要像这样格式化:
$collection = Mage::getModel('enterprise_invitation/invitation')->getCollection();
$collection->addFieldToFilter(array('status', 'customer_id'), array(
array('status','eq'=>'new'),
array('customer_id', 'eq'=>'1234') ));
Now to see what this looks like you can always echo the query that this creates by using
现在看看这是什么样子,您可以随时回显这通过使用创建的查询
echo $collection->getSelect()->__toString();
回答by Gabriel
This is the real magento way:
这是真正的 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
)
)
);
回答by De Nguyen
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()
);
}
Result:
结果:
WHERE (((e.sku like 'a%') or (e.sku like 'b%')))
回答by XPS
To create simple OR condition for collection, use format below:
要为集合创建简单的 OR 条件,请使用以下格式:
$orders = Mage::getModel('sales/order')->getResourceCollection();
$orders->addFieldToFilter(
'status',
array(
'processing',
'pending',
)
);
This will produce SQL like this:
这将产生这样的 SQL:
WHERE (((`status` = 'processing') OR (`status` = 'pending')))