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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:14:16  来源:igfitidea点击:

Magento addFieldToFilter: Two fields, match as OR, not AND

phpmagentomagento-1.9

提问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_firstnameand remote_ip. Here's my (disfunctional without hacking Db.php) code:

我需要做的就是获取一个集合并按两个或多个字段对其进行过滤。说,customer_firstnameremote_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 orcondition 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%')))

Source: http://alanstorm.com/magento_collections

来源:http: //alanstorm.com/magento_collections

回答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')))