设为首页 收藏本站
查看: 246|回复: 0

[经验分享] MySQL数据库对dvbbs.php全文搜索的完全分析

[复制链接]
发表于 2016-10-19 10:07:13 | 显示全部楼层 |阅读模式
  好几天都没有更新文章了,唉,人就是懒呀。
  首先,大家先去下载一份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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-288326-1-1.html 上篇帖子: MySQL解压版在xp下的启动与停止和一些技巧 下篇帖子: MySQL外键 Cannot add or update a child row错误的实例解释
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表