在线
客服

在线客服
尊敬的客户,我们24小时竭诚为您服务 公司总机: 0755-83312037 (32条线)

客服
热线

0755-83312037 (32条线)
7*24小时客服服务热线

?

关注
微信

关注官方微信
TOP

返回
顶部

mysql全文搜索:sql的写法

发布时间:2019-04-13浏览次数:957 <p> </p> <table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0"><tbody><tr> <td style="WORD-WRAP: break-word" bgcolor="#fdfddf"> <font color="#ff0000">WebjxCom提示:</font><font color="#000000">MySQL数据库对dvbbs.php全文搜索的完全分析.</font> </td> </tr></tbody></table> <p>首先,大家先去下载一份dvbbs.php beta1的代码,解压后先抛开php代码,找出你的mysql手册,如果没有手册那么就直接看下面的实例操作吧! </p> <p>mysql全文搜索,sql的写法: </p> <p>MATCH (col1,col2,…) AGAINST (expr [IN BOOLEAN MODE | WITH QUERY EXPANSION]) </p> <p>比如: </p> <p>SELECT * FROM articles WHERE MATCH (title,body) AGAINST (’database’); </p> <p>MATCH()函数对于一个字符串执行资料库内的自然语言搜索。一个资料库就是1套1个或2个包含在FULLTEXT内的列。搜索字符串作为对 AGAINST()的参数而被给定。对于表中的每一行, MATCH() 返回一个相关值,即, 搜索字符串和 MATCH()表中指定列中该行文字之间的一个相似性度量。 </p> <p>下面的例子则更加复杂。询问返回相关值,同时对行按照相关性渐弱的顺序进行排序。为实现这个结果,你应该两次指定 MATCH(): 一次在 SELECT 列表中而另一次在 WHERE子句中。这不会引起额外的内务操作,原因是MySQL 优化程序注意到两个MATCH()调用是相同的,从而只会激活一次全文搜索代码。 </p> <p> </p> <table style="BORDER-BOTTOM: #0099cc 1px solid; BORDER-LEFT: #0099cc 1px solid; TABLE-LAYOUT: fixed; BORDER-TOP: #0099cc 1px solid; BORDER-RIGHT: #0099cc 1px solid" border="0" cellspacing="0" cellpadding="6" width="95%" align="center"><tbody><tr> <td style="WORD-WRAP: break-word" bgcolor="#ddedfb"> <p><font color="#ff0000">以下为引用的内容:</font></p> <p>mysql&gt; SELECT id, body, MATCH <br>(title,body) AGAINST<br>-&gt; (’Security implications of <br>running MySQL as root’) AS score<br>-&gt; FROM articles WHERE MATCH <br>(title,body) AGAINST<br>-&gt; (’Security implications of <br>running MySQL as root’);</p> </td> </tr></tbody></table> <p>所以,到这里你应该会mysql 英文全文搜索了. </p> <p>请注意一个问题. </p> <p>一些词在全文搜索中会被忽略: </p> <p>* 任何过于短的词都会被忽略。 全文搜索所能找到的词的默认最小长度为 4个字符。 </p> <p>* 停止字中的词会被忽略。 </p> <p>mysql还自带查询扩展功能.这里不做过多讨论. </p> <p>下面进行php中文全文搜索的分析 </p> <p>曾经有一个版本的mysql支持中文全文搜索(海量 mysql chinese+,说是GPL但是最终没有开源) </p> <p>中文全文搜索的关键是在分词上.mysql本身不支持cjk的分词(cjk:chinese,japanese,korean), </p> <p>所以 </p> <p>!!!!****如何用php模拟分词是mysql全文索引的关键****!!!! </p> <p>中文分词是语言分词中最困难的.现在也没有人能够彻底完美的解决(虽然这些搜索引擎做的都还不错.) </p> <p> </p> <table style="BORDER-BOTTOM: #0099cc 1px solid; BORDER-LEFT: #0099cc 1px solid; TABLE-LAYOUT: fixed; BORDER-TOP: #0099cc 1px solid; BORDER-RIGHT: #0099cc 1px solid" border="0" cellspacing="0" cellpadding="6" width="95%" align="center"><tbody><tr> <td style="WORD-WRAP: break-word" bgcolor="#ddedfb"> <p><font color="#ff0000">以下为引用的内容:</font></p> <p>//fcicq:下面给大家看看这里php的分词是怎么做的.<br>function &amp;DV_ChineseWordSegment($str,$encodingName=’gbk’){</p> <p>static $objEnc = null;</p> <p>if( $objEnc === null ){</p> <p>if( !class_exists(’DV_Encoding’) ){</p> <p>require_once ROOT_PATH.’inc/DV_Encoding.class.php’;</p> <p>}</p> <p>$objEnc =&amp; DV_Encoding::GetEncoding($encodingName);</p> <p>}</p> <p>$strLen = $objEnc-&gt;StrLength($str);</p> <p>$returnVal = array();</p> <p>if( $strLen &lt; = 1 ){</p> <p>return $str;</p> <p>}</p> <p>$arrStopWords =&amp; DV_GetStopWordList();</p> <p>//print_r($arrStopWords);</p> <p>//过滤所有HTML标签</p> <p>$str = preg_replace('#&lt;[a-zA-Z]+?.*?&gt;|#is’, ”, $str);</p> <p>//过滤所有stopword</p> <p>$str = str_replace($arrStopWords[’StrRepl’],’ ‘,$str);</p> <p>$str = preg_replace($arrStopWords[’PregRepl’],’ ‘,$str);</p> <p>//echo “$str:{$str}<br>“;</p> <p>$arr = explode(’ ‘,$str);</p> <p>//fcicq:好了,这下面的才是php分词关键 *************<br>foreach( $arr as $tmpStr ){</p> <p>if ( preg_match(”/^[x00-x7f]+$/i”,$tmpStr) === 1 ) <br>{ //fcicq:全是E文,没关系,mysql可以认识的</p> <p>$returnVal[] = ‘ ‘.$tmpStr;</p> <p>} else{ //fcicq:中英混合…</p> <p>preg_match_all(”/([a-zA-Z]+)/i”, $tmpStr, $matches);</p> <p>if( !empty($matches) ){ //fcicq:英语部分</p> <p>foreach( $matches[0] as $matche ){</p> <p>$returnVal[] = $matche;</p> <p>}</p> <p>}</p> <p>//过滤ASCII字符</p> <p>$tmpStr = preg_replace(”/([x00-x7f]+)/i”, ”<br>, $tmpStr); //fcicq:你看,剩下的不就全是中文了?</p> <p>$strLen = $objEnc-&gt;StrLength($tmpStr)-1;</p> <p>for( $i = 0 ; $i &lt; $strLen ; $i++ ){</p> <p>$returnVal[] = $objEnc-&gt;SubString($tmpStr,$i,2)<br>; //fcicq:注意这里的substr,不是手册上的.<br>//fcicq:你仔细看,所有的词都是分成两个.<br>//比如”数据库的应用”,会被分成数据 据库 库的 的应 应用…<br>//全文搜索: 全文 文搜 搜索<br>//这分词自然是不怎么样的<br>//但是,搜索的时候同样这么做.<br>//比如搜索数据库,就相当于搜索了数据 据库.<br>//这是一种相当传统的全文搜索分词方法.</p> <p>}</p> <p>}</p> <p>}</p> <p>return $returnVal;</p> <p>}//end function DV_ChineseWordSegment</p> <p>//fcicq:这就是传说中的substr.偶相信许多人写出来的php代码都比这个好.<br>function &amp;SubString(&amp;$str,$start,$length=null){</p> <p>if( !is_numeric($start) ){</p> <p>return false;</p> <p>}</p> <p>$strLen = strlen($str);</p> <p>if( $strLen &lt; = 0 ){</p> <p>return false;</p> <p>}</p> <p>if( $start &lt; 0 || $length &lt; 0 ){</p> <p>$mbStrLen = $this-&gt;StrLength($str);</p> <p>} else{</p> <p>$mbStrLen = $strLen;</p> <p>}</p> <p>if( !is_numeric($length) ){</p> <p>$length = $mbStrLen;</p> <p>} elseif( $length &lt; 0 ){</p> <p>$length = $mbStrLen + $length - 1;</p> <p>}</p> <p>if( $start &lt; 0 ){</p> <p>$start = $mbStrLen + $start;</p> <p>}</p> <p>$returnVal = '';</p> <p>$mbStart = 0;</p> <p>$mbCount = 0;</p> <p>for( $i = 0 ; $i &lt; $strLen ; $i++ ){</p> <p>if( $mbCount &gt;= $length ){</p> <p>break;</p> <p>}</p> <p>$currOrd = ord($str{$i});</p> <p>if( $mbStart &gt;= $start ){</p> <p>$returnVal .= $str{$i};</p> <p>if( $currOrd &gt; 0×7f ){</p> <p>$returnVal .= $str{$i+1}.$str{$i+2};</p> <p>$i += 2;</p> <p>}</p> <p>$mbCount++;</p> <p>} elseif( $currOrd &gt; 0×7f ){</p> <p>$i += 2;</p> <p>}</p> <p>$mbStart++;</p> <p>}</p> <p>return $returnVal;</p> <p>}//end function SubString</p> <p>//插入全文搜索分词表.一共两个,一个 topic_ft,一个bbs_ft</p> <p>$arrTopicIndex =&amp; DV_ChineseWordSegment($topic);</p> <p>if( !empty($arrTopicIndex) &amp;&amp; is_array($arrTopicIndex) ){</p> <p>$topicindex = $db-&gt;escape_string(implode(’ ‘,$arrTopicIndex));</p> <p>if( $topicindex !== ” ){</p> <p>$db-&gt;query(”UPD ATE {$dv}topic_ft SET topicindex=’<br>{$topicindex}’ WHERE topicid=’{$RootID}’”);</p> <p>} else{</p> <p>$db-&gt;query(”DEL ETE FROM {$dv}topic_ft<br>&#160;WHERE topicid=’{$RootID}’”);</p> <p>}</p> <p>}<br>}</p> </td> </tr></tbody></table> <p>这就是所谓的mysql全文搜索分词,mysql不会分词,而php会。就这么简单。</p> <p>这虽然是一种比较过时的方法,但是非常实用。</p>