[笔记]MySQL数据库对dvbbs.php全文搜索的完全分析_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2318 | 回复: 0   主题: [笔记]MySQL数据库对dvbbs.php全文搜索的完全分析        下一篇 
谁是天蝎
注册用户
等级:大元帅
经验:90210
发帖:106
精华:0
注册:2011-7-21
状态:离线
发送短消息息给谁是天蝎 加好友    发送短消息息给谁是天蝎 发消息
发表于: IP:您无权察看 2014-12-19 9:17:57 | [全部帖] [楼主帖] 楼主

首先,大家先去下载一份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会。就这么简单。

这虽然是一种比较过时的方法,但是非常实用。

--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论