使用LIKE过滤结果


16

考虑以下三个“干草堆”字符串:

一种) foo bar

b) welcome to foo bar industries

C) foo barer

现在我的“针”:

foo bar

(呵呵)

我希望我的过滤器使我的针头与干草堆字符串a和b匹配,但不与c匹配。我试过了:

$collection->addAttributeToFilter('name', array('like' => '%'.$needle.'%'));

但以上与c匹配。

我也尝试过:

$collection->addAttributeToFilter('name', array('like' => '% '.$needle.' %')); // Note the spaces

以上仅与b匹配。

任何帮助深表感谢。

Answers:


37

试试看,看是否合适:

$collection->addAttributeToFilter('name', array(
    array('like' => '% '.$needle.' %'), //spaces on each side
    array('like' => '% '.$needle), //space before and ends with $needle
    array('like' => $needle.' %') // starts with needle and space after
));

将第二个参数作为数组数组传递时,将使用 OR


那有效:)不知道数组技巧,谢谢。
Bealalex 2013年

对于自定义/非eav模型,addAttributeToFilter应替换为addFieldToFilter
jvalanen '16

有没有办法确定哪个数组返回结果?我正在使用此方法搜索自定义模型集合(名称,描述,alternate_name字段),并且我想知道是否由于描述而导致结果被击中(在搜索结果中包括其他UI元素)。
pspahn '18年

3
@pspahn不是直接的。执行选择后,您可以遍历结果,并检查是否在所需的任何字段中找到了针。
马里斯(Marius)

9

一个可能的解决方案是使用REGEXP而不是LIKE

$collection->addAttributeToFilter('name', array('regexp' => '[[:<:]]'.$needle.'[[:>:]]'));

MySQL文档

[[:<:]],[[:>:]]

这些标记代表单词边界。它们分别匹配单词的开头和结尾。单词是单词字符的序列,不能在单词字符之前或之后。单词字符是alnum类中的字母数字字符或下划线(_)。

请注意,如果$needle可以在POSIX正则表达式中包含具有特殊含义的字符,则需要对其进行转义。另请参阅:https : //stackoverflow.com/questions/4024188/php-function-to-escape-mysql-regexp-syntax


3

接受的答案无法正常工作。它仅检查文本前后的空间。

假设您有以下列表

  • 夹克
  • 夏季外套
  • 冬季夹克

现在,如果您尝试使用接受的答案搜索夹克,它将仅返回Summer JacketWinter Jacket

我认为以下解决方案更好

$collection->addAttributeToFilter('name', array('like' => '%' . $needle. '%'));

它不会涵盖问题中的情况(c)(即也匹配“装套”)。取而代之的是,['eq' => $needle]可以添加第四个条件来查找完全匹配(或者更好的是,使用正则表达式解决方案来查找所有边界,而不仅是空格)
Fabian Schmengler,

上面的代码能够找到确切的匹配项。我检查了它
Dinesh Yadav

我毫不怀疑。但是它找到了更多,这是不应该的。至少如果您具有与原始问题相同的要求:搜索“ foo bar”时不要找到“ foo
barer

你是对的。可接受的答案不适用于我,因此我建议使用简单的单行过滤器来获取同样的项目。
Dinesh Yadav '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.