mysql全文搜索 sql命令的写法

  • A+
所属分类:数据库技术

首先,大家先去下载一份dvbbs.php beta1的代码,解压后先抛开php代码,找出你的mysql手册,如果没有手册那么就直接看下面的实例操作吧!

mysql全文搜索,sql的写法:

MATCH (col1,col2,…) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION])

比如:

SELECT * FROM articles WHERE MATCH (title,body) AGAINST ('database');

MATCH()函数对于一个字符串执行资料库内的自然语言搜索。一个资料库就是1套1个或2个包含在FULLTEXT内的列。搜索字符串作为对 AGAINST()的参数而被给定。对于表中的每一行, MATCH() 返回一个相关值,即, 搜索字符串和 MATCH()表中指定列中该行文字之间的一个相似性度量。

下面的例子则更加复杂。询问返回相关值,同时对行按照相关性渐弱的顺序进行排序。为实现这个结果,你应该两次指定 MATCH(): 一次在 SELECT 列表中而另一次在 WHERE子句中。这不会引起额外的内务操作,原因是MySQL 优化程序注意到两个MATCH()调用是相同的,从而只会激活一次全文搜索代码。

  1. mysql> SELECT id, body, MATCH
  2. (title,body) AGAINST
  3. -> ('Security implications of
  4. running MySQL as root') AS score
  5. -> FROM articles WHERE MATCH
  6. (title,body) AGAINST
  7. -> ('Security implications of
  8. running MySQL as root');

所以,到这里你应该会mysql 英文全文搜索了.

请注意一个问题.

一些词在全文搜索中会被忽略:

* 任何过于短的词都会被忽略。 全文搜索所能找到的词的默认最小长度为 4个字符。

* 停止字中的词会被忽略。

mysql还自带查询扩展功能.这里不做过多讨论.下面进行

php中文全文搜索的分析

曾经有一个版本的mysql支持中文全文搜索(海量 mysql chinese+,说是GPL但是最终没有开源)

中文全文搜索的关键是在分词上.mysql本身不支持cjk的分词(cjk:chinese,japanese,korean),

所以

!!!!****如何用php模拟分词是mysql全文索引的关键****!!!!

中文分词是语言分词中最困难的.现在也没有人能够彻底完美的解决(虽然这些搜索引擎做的都还不错.)

  1. //fcicq:下面给大家看看这里php的分词是怎么做的. 
  2. function &DV_ChineseWordSegment($str,$encodingName='gbk'){
  3. static $objEnc = null;
  4. if( $objEnc === null ){
  5. if( !class_exists('DV_Encoding') ){
  6. require_once ROOT_PATH.'inc/DV_Encoding.class.php';
  7. }
  8. $objEnc =& DV_Encoding::GetEncoding($encodingName);
  9. }
  10. $strLen = $objEnc->StrLength($str);
  11. $returnVal = array();
  12. if( $strLen < = 1 ){
  13. return $str;
  14. }
  15. $arrStopWords =& DV_GetStopWordList();
  16. //print_r($arrStopWords); 
  17. //过滤所有HTML标签 
  18. $str = preg_replace('#<[a-zA-Z]+?.*?>|#is', ”, $str);
  19. //过滤所有stopword 
  20. $str = str_replace($arrStopWords['StrRepl'],' ‘,$str);
  21. $str = preg_replace($arrStopWords['PregRepl'],' ‘,$str);
  22. //echo “$str:{$str} 
  23. “;
  24. $arr = explode(' ‘,$str);
  25. //fcicq:好了,这下面的才是php分词关键 ************* 
  26. foreach( $arr as $tmpStr ){
  27. if ( preg_match(”/^[x00-x7f]+$/i”,$tmpStr) === 1 )
  28. //fcicq:全是E文,没关系,mysql可以认识的 
  29. $returnVal[] = ‘ ‘.$tmpStr;
  30. else//fcicq:中英混合… 
  31. preg_match_all(”/([a-zA-Z]+)/i”, $tmpStr, $matches);
  32. if( !empty($matches) ){ //fcicq:英语部分 
  33. foreach( $matches[0] as $matche ){
  34. $returnVal[] = $matche;
  35. }
  36. }
  37. //过滤ASCII字符 
  38. $tmpStr = preg_replace(”/([x00-x7f]+)/i”, ”
  39. , $tmpStr); //fcicq:你看,剩下的不就全是中文了? 
  40. $strLen = $objEnc->StrLength($tmpStr)-1;
  41. for( $i = 0 ; $i < $strLen ; $i++ ){
  42. $returnVal[] = $objEnc->SubString($tmpStr,$i,2)
  43. //fcicq:注意这里的substr,不是手册上的. 
  44. //fcicq:你仔细看,所有的词都是分成两个. 
  45. //比如”数据库的应用”,会被分成数据 据库 库的 的应 应用… 
  46. //全文搜索: 全文 文搜 搜索 
  47. //这分词自然是不怎么样的 
  48. //但是,搜索的时候同样这么做. 
  49. //比如搜索数据库,就相当于搜索了数据 据库. 
  50. //这是一种相当传统的全文搜索分词方法. 
  51. }
  52. }
  53. }
  54. return $returnVal;
  55. }//end function DV_ChineseWordSegment 
  56. //fcicq:这就是传说中的substr.偶相信许多人写出来的php代码都比这个好. 
  57. function &SubString(&$str,$start,$length=null){
  58. if( !is_numeric($start) ){
  59. return false;
  60. }
  61. $strLen = strlen($str);
  62. if( $strLen < = 0 ){
  63. return false;
  64. }
  65. if( $start < 0 || $length < 0 ){
  66. $mbStrLen = $this->StrLength($str);
  67. else{
  68. $mbStrLen = $strLen;
  69. }
  70. if( !is_numeric($length) ){
  71. $length = $mbStrLen;
  72. } elseif( $length < 0 ){
  73. $length = $mbStrLen + $length - 1;
  74. }
  75. if( $start < 0 ){
  76. $start = $mbStrLen + $start;
  77. }
  78. $returnVal = '';
  79. $mbStart = 0;
  80. $mbCount = 0;
  81. for( $i = 0 ; $i < $strLen ; $i++ ){
  82. if( $mbCount >= $length ){
  83. break;
  84. }
  85. $currOrd = ord($str{$i});
  86. if( $mbStart >= $start ){
  87. $returnVal .= $str{$i};
  88. if( $currOrd > 0×7f ){
  89. $returnVal .= $str{$i+1}.$str{$i+2};
  90. $i += 2;
  91. }
  92. $mbCount++;
  93. } elseif( $currOrd > 0×7f ){
  94. $i += 2;
  95. }
  96. $mbStart++;
  97. }
  98. return $returnVal;
  99. }//end function SubString 
  100. //插入全文搜索分词表.一共两个,一个 topic_ft,一个bbs_ft 
  101. $arrTopicIndex =& DV_ChineseWordSegment($topic);
  102. if( !empty($arrTopicIndex) && is_array($arrTopicIndex) ){
  103. $topicindex = $db->escape_string(implode(' ‘,$arrTopicIndex));
  104. if( $topicindex !== ” ){
  105. $db->query(”UPD ATE {$dv}topic_ft SET topicindex='
  106. {$topicindex}' WHERE topicid='{$RootID}'”);
  107. else{
  108. $db->query(”DEL ETE FROM {$dv}topic_ft
  109. WHERE topicid='{$RootID}'”);
  110. }
  111. }
  112. }

这就是所谓的mysql全文搜索分词,mysql不会分词,而php会。就这么简单。
这虽然是一种比较过时的方法,但是非常实用。