Magento addFieldToFilter:两个字段,匹配为OR,而不是AND

Gab*_*l H 42 php magento magento-1.9

过去几个小时我一直坚持这个.我通过乱砍几行来解决这个问题/lib/Varien/Data/Collection/Db.php,但是我宁愿使用正确的解决方案并保持我的核心不受影响.

我需要做的就是获取一个集合并通过两个或多个字段对其进行过滤.说,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)));
Run Code Online (Sandbox Code Playgroud)

有了股票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'),           
));
Run Code Online (Sandbox Code Playgroud)

但这给了我这个错误:

Warning: Illegal offset type in isset or empty  in magento/lib/Varien/Data/Collection/Db.php on line 369
Run Code Online (Sandbox Code Playgroud)

如果我用try/catch包装它,那么它会进入_getConditionSql()并给出这个错误:

Warning: Invalid argument supplied for foreach()  in magento/lib/Varien/Data/Collection/Db.php on line 412
Run Code Online (Sandbox Code Playgroud)

有没有人有任何工作,功能代码这样做?我正在运行Magento 1.9(企业版).谢谢!

小智 72

我还有另一种方法可以or在现场添加条件:

->addFieldToFilter(
    array('title', 'content'),
    array(
        array('like'=>'%$titlesearchtext%'), 
        array('like'=>'%$contentsearchtext%')
    )
)
Run Code Online (Sandbox Code Playgroud)


CJ *_*nis 24

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
    )
);
Run Code Online (Sandbox Code Playgroud)

这将生成一个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'))
    )
Run Code Online (Sandbox Code Playgroud)

每个嵌套数组(<condition>)为OR条件生成另一组括号.


小智 16

我也试过了 field1 = 'a' OR field2 = 'b'

你的代码对我不起作用.

这是我的解决方案

$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());
Run Code Online (Sandbox Code Playgroud)

它给了我

SELECT name, keywords FROM abc WHERE keywords like '%foo%' OR additional_keywords like '%bar%'.

它可能不是"magento的方式",但我被困了5个小时.

希望它会有所帮助


Mic*_*yne 11

这是我在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),
                    )
            );
Run Code Online (Sandbox Code Playgroud)

这导致了这个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)))
Run Code Online (Sandbox Code Playgroud)


小智 9

要按多个属性过滤,请使用以下内容:

//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')
            )
        );
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请访问:http: //docs.magentocommerce.com/Varien/Varien_Data/Varien_Data_Collection_Db.html#_getConditionSql

  • 这仅适用于EAV集合中的addAttributeToFilter.Riyazkhan的答案是正确的. (3认同)

jaz*_*kat 7

谢谢安达,你的帖子得到了很大的帮助!然而,OR句子对我来说并不合适,而且我得到了一个错误: getCollection()"为foreach提供了无效的参数".

所以这就是我的结果(注意在这种情况下指定属性3次而不是2次):

  $collection->addFieldToFilter('attribute', array(  
    array('attribute'=>'my_field1','eq'=>'my_value1'),            
    array('attribute'=>'my_field2','eq'=>'my_value2') ));
Run Code Online (Sandbox Code Playgroud)

addFieldToFilter首先需要一个字段然后条件 - > 链接.


小智 5

这里有一些混乱,但让我试着澄清一些事情:

让我们说你想要的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')
)
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,您的集合需要格式化如下:

$collection = Mage::getModel('enterprise_invitation/invitation')->getCollection();

$collection->addFieldToFilter(array('status', 'customer_id'), array(
array('status','eq'=>'new'),
array('customer_id', 'eq'=>'1234') ));
Run Code Online (Sandbox Code Playgroud)

现在看看它看起来像什么,你总是可以通过使用来回显这个创建的查询

echo $collection->getSelect()->__toString();
Run Code Online (Sandbox Code Playgroud)