在mysql表中搜索5个关键字

时间:2014-09-08 05:29:52

标签: php mysql search full-text-search sql-like

我正在尝试从用户在MySQL表中输入的标签中搜索关键字,并根据匹配数返回最佳结果。

代码:

MySQL结构:

 id    | keywords       | phrase
 1     | apple king pearl   | I was eating an apple when the king hit me
 2     | brush brute fancy  | you fancy this brush?   
 3     | king queen kingdom | shall the queen obey the king or the kingdom?

PHP:

 $keywords_raw='me wall like king apple'   //define keywords based on the tags the user inputs
 $keywords=explode(' ', $keywords_raw);

.... 这就是我被卡住的地方。我的意见是:

  1. 将对每个关键字执行搜索,例如“我”,“墙”,“喜欢”等等

  2. 对于每个关键字,它将在表的每一行中搜索“keywords”和“phrase”两列,并返回找到的匹配数。例如,搜索针对第一行输入的关键字将返回关键字“me”具有0个匹配,“wall”具有0个匹配,“like”0,“king”2和“apple”2。因此总匹配将是2 +2 = 4.

  3. 最后,比较从所有行中找到的匹配总数,然后选择匹配最多的前3行。
  4. #2的一个问题是如何忽略包含搜索关键字的单词,例如“kingdom”包含“king”但是是一个不同的单词。


    更新

    根据有用的答案,我使用了全文搜索。

        $keywords='bb';
    
        $data['recommendation']=$this->db->query
        ("SELECT *, MATCH(keywords, phrase) AGAINST ('$keywords') as score 
        FROM game
        WHERE MATCH(keywords, phrase) AGAINST ('$keywords') 
        ORDER BY score 
        LIMIT 3");
    
        var_dump($data['recommendation']);
        die;
    

    由于某种原因,var_dump返回一个没有找到行的空结果。但是我在表格的至少2行中确实有“bb”这个短语,如下所示。

     id    | keywords       | phrase
     1     | bb king        | I was eating an apple when bb the king hit me
     2     | bb             | you fancy this brush?   
    

2 个答案:

答案 0 :(得分:2)

正如Barmar所说,你可以使用全文功能:

SELECT id, customer_id, phrase 
FROM table
WHERE MATCH(phrase) AGAINST ('me wall like king apple');

如果还需要搜索其他列,请将其添加到MATCH

SELECT id, customer_id, phrase 
FROM table
WHERE MATCH(phrase,keywords) AGAINST ('me wall like king apple');

编辑:

对于第3点,您可以使用相同的功能:

SELECT id, customer_id, phrase, MATCH(phrase,keywords) AGAINST ('me wall like king apple') as score 
FROM table
WHERE MATCH(phrase,keywords) AGAINST ('me wall like king apple') 
ORDER BY score 
LIMIT 3;

此查询将返回三个最佳匹配

了解更多信息take a look to the manual

更新:

根据手册:

  

全文搜索中会忽略某些字词:

     
      
  • 任何太短的单词都会被忽略。通过全文搜索找到的默认最小单词长度为四个字符。

  •   
  • 会忽略禁用词列表中的字词。禁用词是诸如“the”或“some”之类的词,它是如此常见以至于它被认为具有零语义值。有一个内置的禁用词列表,但它可以被用户定义的列表覆盖。

  •   

您使用简短的字词进行搜索,这就是您没有得到任何结果的原因。

更新09-09-14:

来自documentation

  

如果修改影响索引编制的全文变量(ft_min_word_lenft_max_word_lenft_stopword_file),或者更改了阻截文件本身,则必须重建{{1进行更改并重新启动服务器后的索引。要在这种情况下重建索引,只需执行FULLTEXT修复操作即可:

     

的MySQL> REPAIR TABLE tbl_name QUICK;

因此,执行QUICK后,您必须执行ALTER TABLE table ADD FULLTEXT(phrase, keywords);仅执行一次

答案 1 :(得分:0)

  $keywords=explode(' ', $keywords_raw);
  if(count($keywords)>1)
                 {
                     $stmt.="(";
                     $i=0;
                     foreach($arr_s1 as $kv)
                     {
                        if($i>0)
                        {
                                $stmt.=" AND ";
                        }
                        $stmt.=" phrase like '%".$kv."%'";                       
                        $i++;
                     }
                     $stmt.=")";                    

                 }

希望它对你有用。