程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> 關於MYSQL數據庫 >> MySQL數據庫對dvbbs.php全文搜索的完全分析

MySQL數據庫對dvbbs.php全文搜索的完全分析

編輯:關於MYSQL數據庫
首先,大家先去下載一份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()調用是相同的,從而只會激活一次全文搜索代碼。

  以下為引用的內容:

  MySQL> SELECT id, body, MATCH

  (title,body) AGAINST

  -> (’Security implications of

  running MySQL as root’) AS score

  -> FROM articles WHERE MATCH

  (title,body) AGAINST

  -> (’Security implications of

  running MySQL as root’);

  所以,到這裡你應該會MySQL 英文全文搜索了.

  請注意一個問題.

  一些詞在全文搜索中會被忽略:

  * 任何過於短的詞都會被忽略。 全文搜索所能找到的詞的默認最小長度為 4個字符。

  * 停止字中的詞會被忽略。

  MySQL還自帶查詢擴展功能.這裡不做過多討論.

  下面進行PHP中文全文搜索的分析

  曾經有一個版本的mysql支持中文全文搜索(海量 MySQL chinese+,說是GPL但是最終沒有開源)

  中文全文搜索的關鍵是在分詞上.MySQL本身不支持cjk的分詞(cjk:chinese,japanese,korean),

  所以

  !!!!****如何用PHP模擬分詞是MySQL全文索引的關鍵****!!!!

  中文分詞是語言分詞中最困難的.現在也沒有人能夠徹底完美的解決(雖然這些搜索引擎做的都還不錯.)

  以下為引用的內容:

  //fcicq:下面給大家看看這裡PHP的分詞是怎麼做的.

  function &DV_ChineseWordSegment($str,$encodingName=’gbk’){

  static $objEnc = null;

  if( $objEnc === null ){

  if( !class_exists(’DV_Encoding’) ){

  require_once ROOT_PATH.’inc/DV_Encoding.class.PHP’;

  }

  $objEnc =& DV_Encoding::GetEncoding($encodingName);

  }

  $strLen = $objEnc->StrLength($str);

  $returnVal = array();

  if( $strLen < = 1 ){

  return $str;

  }

  $arrStopWords =& DV_GetStopWordList();

  //print_r($arrStopWords);

  //過濾所有Html標簽

  $str = preg_replace('#<[a-zA-Z]+?.*?>|#is’, ”, $str);

  //過濾所有stopWord

  $str = str_replace($arrStopWords[’StrRepl’],’ ‘,$str);

  $str = preg_replace($arrStopWords[’PregRepl’],’ ‘,$str);

  //echo “$str:{$str}

  “;

  $arr = explode(’ ‘,$str);

  //fcicq:好了,這下面的才是PHP分詞關鍵 *************

  foreach( $arr as $tmpStr ){

  if ( preg_match(”/^[x00-x7f]+$/i”,$tmpStr) === 1 )

  { //fcicq:全是E文,沒關系,MySQL可以認識的

  $returnVal[] = ‘ ‘.$tmpStr;

  } else{ //fcicq:中英混合…

  preg_match_all(”/([a-zA-Z]+)/i”, $tmpStr, $matches);

  if( !empty($matches) ){ //fcicq:英語部分

  foreach( $matches[0] as $matche ){

  $returnVal[] = $matche;

  }

  }

  //過濾ASCII字符

  $tmpStr = preg_replace(”/([x00-x7f]+)/i”, ”

  , $tmpStr); //fcicq:你看,剩下的不就全是中文了?

  $strLen = $objEnc->StrLength($tmpStr)-1;

  for( $i = 0 ; $i < $strLen ; $i++ ){

  $returnVal[] = $objEnc->SubString($tmpStr,$i,2)

  ; //fcicq:注意這裡的substr,不是手冊上的.

  //fcicq:你仔細看,所有的詞都是分成兩個.

  //比如”數據庫的應用”,會被分成數據 據庫 庫的 的應 應用…

  //全文搜索: 全文 文搜 搜索

  //這分詞自然是不怎麼樣的

  //但是,搜索的時候同樣這麼做.

  //比如搜索數據庫,就相當於搜索了數據 據庫.

  //這是一種相當傳統的全文搜索分詞方法.

  }

  }

  }

  return $returnVal;

  }//end function DV_ChineseWordSegment

  //fcicq:這就是傳說中的substr.偶相信許多人寫出來的PHP代碼都比這個好.

  function &SubString(&$str,$start,$length=null){

  if( !is_numeric($start) ){

  return false;

  }

  $strLen = strlen($str);

  if( $strLen < = 0 ){

  return false;

  }

  if( $start < 0 || $length < 0 ){

  $mbStrLen = $this->StrLength($str);

  } else{

  $mbStrLen = $strLen;

  }

  if( !is_numeric($length) ){

  $length = $mbStrLen;

  } elseif( $length < 0 ){

  $length = $mbStrLen + $length - 1;

  }

  if( $start < 0 ){

  $start = $mbStrLen + $start;

  }

  $returnVal = '';

  $mbStart = 0;

  $mbCount = 0;

  for( $i = 0 ; $i < $strLen ; $i++ ){

  if( $mbCount >= $length ){

  break;

  }

  $currOrd = ord($str{$i});

  if( $mbStart >= $start ){

  $returnVal .= $str{$i};

  if( $currOrd > 0×7f ){

  $returnVal .= $str{$i+1}.$str{$i+2};

  $i += 2;

  }

  $mbCount++;

  } elseif( $currOrd > 0×7f ){

  $i += 2;

  }

  $mbStart++;

  }

  return $returnVal;

  }//end function SubString

  //插入全文搜索分詞表.一共兩個,一個 topic_ft,一個bbs_ft

  $arrTopicIndex =& DV_ChineseWordSegment($topic);

  if( !empty($arrTopicIndex) && is_array($arrTopicIndex) ){

  $topicindex = $db->escape_string(implode(’ ‘,$arrTopicIndex));

  if( $topicindex !== ” ){

  $db->query(”UPD ATE {$dv}topic_ft SET topicindex=’

  {$topicindex}’ WHERE topicid=’{$RootID}’”);

  } else{

  $db->query(”DEL ETE FROM {$dv}topic_ft

  WHERE topicid=’{$RootID}’”);

  }

  }

  }

  這就是所謂的mysql全文搜索分詞,MySQL不會分詞,而PHP會。就這麼簡單。

  這雖然是一種比較過時的方法,但是非常實用。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved