【问题标题】:Improve mysql search results with wildcards. Joomla 3.3使用通配符改进 mysql 搜索结果。 Joomla 3.3
【发布时间】:2024-09-12 07:55:01
【问题描述】:

我的 mvc 模型中有一个过滤器,它从搜索字段中获取一个变量。它搜索标题等,但搜索结果很差。这可能是一个简单的语法问题,但我无法看到它搜索。

我有一些项目标题,例如:

“Manolo Blahnik Carolyne 金色闪光露跟高跟鞋(35.5,金色)” 或者 “Belstaff Trialmaster 夹克”

目前,如果您搜索“manolo blahnik shoes”或“belstaff Jacket”,您不会得到任何结果。如何从字符串的任何部分匹配任何单词?

我尝试将 % 添加到变量的任一侧,例如 %'.$keyword.'% 但这不起作用。

//Filtering search field
    $jinput = JFactory::getApplication()->input;
    $keyword = $jinput->get('keyword', '', 'NULL');
    if($keyword!=''){
         $keyword = $db->Quote('%' . $db->escape($keyword, true) . '%');
            $query->where('( a.title LIKE '.$keyword.'  OR  a.features LIKE '.$keyword.'       OR  a.brand LIKE '.$keyword.' )');
    }

【问题讨论】:

  • 你期待什么?标题是否应包含所有单词或至少一个单词。例如,您的 manolo 示例在搜索中有鞋子,但确实有 manolo 和 blahnik。它还必须有所有的单词,单词的顺序是什么?
  • 不,顺序无关紧要,它应该匹配字符串中至少有一个单词的位置。

标签: php mysql


【解决方案1】:

我认为您最好的选择是爆炸您获得的搜索刺痛并从中创建 OR

所以

$keyword = "manolo blahnik shoes";
$keyWords = explode(' ', $keyword);

$ors = array();

foreach($keywords as $word) {
     $word = $db->Quote('%' . $db->escape($word, true) . '%');
     $ors[] = "a.title LIKE %word";
     $ors[] = "a.features LIKE $word";
     $ors[] = "a.title brand LIKE $word"
}

$queryString = implode(' OR ', $ors');
$query->where($queryString);

由于只有一个单词应该出现在 3 列之一中,因此您可以拥有一整串 OR。

当然,这可能会变成一个相当大的查询,所以也许你必须牢记这一点。

此外,此代码是一个示例,您可以根据需要进行更改,例如确保 $keywords 在爆炸之前不为空,转义您获得的关键字或使用准备好的语句来防止类似的 sql 注入。

对于这样的事情,甚至可能明智地使用 solr 进行搜索,而不是直接使用 mysql 进行搜索。或者,如果您有 myisam 表,您可以查看全文搜索 mysql FULLTEXT search multiple words

【讨论】: