中文全文检索

原创
2016/12/27 22:33
阅读数 182

中文全文检索 MySQL不支持中文全文检索,因为中文一句话是连着写的,不像英文单词间有空格分隔。解决办法就是中文分词(关于中文分词请参阅其它文章),如果你的MySQL是安装在Windows平台上的,可以不用转码直接存储中文就可以使用全文索引,如本例。但是如果你的MySQL是安装在Linux上的则需要进行转编码(urlencode / base64_encode / json_encode / 区位 / 拼音)等方案,具体方案参看其它博文。

MYSQL全文搜索通过 MATCH() 函数完成。

  下面举一简单例子:

  1、新建数据表:

  CREATE TABLE fulltext_sample(copy TEXT,FULLTEXT(copy)) TYPE=MyISAM;

  这里的copy就是一个fulltext类型的字段,如果建表的时候没有添加全文检索字段,也可以通过alert来添加,如:

  ALTER TABLE fulltext_sample ADD FULLTEXT(copy)

  2、插入数据:

  INSERT INTO fulltext_sample VALUES

  ('It appears good from here'),

  ('The here and the past'),

  ('Why are we hear'),

  ('An all-out alert'),

  ('All you need is love'),

  ('A good alert');

  3、数据检索:

  SELECT * FROM fulltext_sample WHERE MATCH(copy) AGAINST('love');

  上面就是mysql的全文检索功能,注意:在全文索引上进行搜索是不区分大小写的。

  下面再看如何实现中文全文检索。

  fulltext字段是以词语为单位,词语之间需要用空格隔开,而汉语的句子中各个词语之间并不会用空格隔开,因此我们需要对中文进行分词,这也就是为什么上面需要强词用到中文分词扩展模块。

  但是尽管对中文进行分词,MYSQL还是不能通过MATCH来实现中文的全文检索,这需要通过一定的方法来进行转换,一个比较简单实用的方法是采用下面这个函数(当然还有更好的),它将中文进行了urlencode转换。

  function q_encode($str)

  {

  $data = array_filter(explode(" ",$str));

  $data = array_flip(array_flip($data));

  foreach ($data as $ss) {

  if (strlen($ss)>1 )

  $data_code .= str_replace("%","",urlencode($ss)) . " ";

  }

  $data_code = trim($data_code);

  return $data_code;

  }

  将转换过后的内容保存至事先定义好的fulltext字段。同样,在查询的时候也需要将查询的关键词进行同样方法的转换。

*、语法 MATCH (col1,col2,...) AGAINST (expr [search_modifier]) search_modifier: { IN BOOLEAN MODE | WITH QUERY EXPANSION }

  例如:SELECT * FROM tab_name WHERE MATCH ('列名1,列名2...列名n') AGAINST('词1 词2 词3 ... 词m');

  即:MATCH 相当于要匹配的列,而 AGAINST 就是要找的内容。  
  这里的table需要是MyISAM类型的表,col1、col2 必须是char、varchar或text类型,在查询之前需要在 col1 和 col2 上分别建立全文索引(FULLTEXT索引)。

*、总结事项 1、预设搜寻是不分大小写,若要分大小写,columne 的 character set要从utf8改成utf8_bin。 2、预设 MATCH...AGAINST 是以相关性排序,由高到低。 3、MATCH(title, content)里的字段必须和FULLTEXT(title, content)里的字段一模一样。 如果只要单查title或content一个字段,那得另外再建一个 FULLTEXT(title) 或 FULLTEXT(content),也因为如此,MATCH()的字段一定不能跨table,但是另外两种搜寻方式好像可以。

http://simonfenci.sinaapp.com/index.php?key=simon&wd=宝奥城玩具城电动玩具 返回: Array ( [0] => Array ( [word] => 宝 [word_tag] => 95 [index] => 0 ) [1] => Array ( [word] => 奥 [word_tag] => 193 [index] => 1 ) [2] => Array ( [word] => 城 [word_tag] => 95 [index] => 2 ) [3] => Array ( [word] => 玩具城 [word_tag] => 95 [index] => 3 ) [4] => Array ( [word] => 电动 [word_tag] => 20 [index] => 4 ) [5] => Array ( [word] => 玩具 [word_tag] => 95 [index] => 5 ) )

*新浪的分司用法 (http://apidoc.sinaapp.com/source-class-SaeSegment.html#12-650) endpoint = "http://segment.sae.sina.com.cn/urlclient.php?encoding=UTF-8" data = { "context": "柯林斯英汉双解大词典", "word_tag": 1 } r = requests.post(endpoint, data=data) r.encoding='utf-8' return r.text


Discuz! 在线中文分词、关键词提取服务 不同于使用自己的服务器进行分词,Discuz!在线中文分词服务是基于API返回分词结果的。在项目中,我们只需要一个函数即可方便地进行分词、关键词提取。 以下是根据Discuz!在线分词服务API写的函数,测试可正常运行:全文:http://www.thinkphp.cn/code/563.html

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部