IT学习者 | 文章大全 | 技术文档 | 桌面壁纸 | 实用查询 | 网络电台 | 成语 | 歇后语 | 网址 | 下载 | 周公解梦 | 生日密码 | 电视剧365 | Flash
 您现在的位置: IT学习者 >> 文章大全 >> 网络编程 >> PHP

让 MySQL 真正支持中文的全文检索(全文索引)

【 作者:hightman    来源:PHPCHINA  更新时间:2007-10-26 | 字体:

PHP 和 MySQL 几乎也是离不开的, 后面我附一个简单的例子来说明在 PHP 中使用全文检索....

下载及完全说明正式地址: http://myft.twomice.net

在不影响 MySQL 的系统结构及其他功能的前提下,解决了 MySQL 目前对中文全文检索无法正确支持的缺陷并优化 MySQL 对中文检索处理的性能。(目前本软件包支持根据词典进行简易的正向最大匹配分词、支持包括UTF-8、GBK、BIG5 ... 在内的字符集)

经测试效果尚可, 140万行约 1.4G 数据(不含索引区空间) 检索大概都在 0.0x ~ 0.x 秒之间. 搭配做一个小型全文检索将变得十分简单.

MySQL 从 3.23 的某个小版本开始就已经支持在 MyISAM 表中建立全文索引的字段。由于 CJK(中日韩)字符集及其句法的特殊性(词与词之间没有像英文一样的间隔),MySQL 一直没有针对多字节的宽字符集作出应有的支持,也没有任何分词能力。

而 MySQL 作为 PHP 等 Web Script 的绝佳搭档,已经被广泛应用到各个角落,对于它的检索令绝大多数开发者头痛,用 SELECT ... WHERE ... LIKE %...% 的方式不仅效率差(动则扫描全表岂能不慢?),对于中文这样的特殊语言也存在严重的岐义问题(因为词才是最小的语意单位)。我也在一段时间内受限于 MySQL 的检索限制,而不得不寻求其它解决方案,但都不太尽人意。

--
顺便提一下,有一个叫作海量的分词技术公司,很早就做过 mysql-chinese 的 hack,只不过迟迟没有按照 GNU 精神及时发布源码,所以才决定自己来作。


-- 用 PHP 配合 MySQL (4.0.x) 的全文检索例子代码 --

<?php
if ($_GET['q'] && $q = trim($_GET['q']))
{
    mysql_connect();
    mysql_select_db("dot66");
    $q = mysql_escape_string($q);
    $r = mysql_query("SELECT SEGMENT('$q')");
    $n = mysql_fetch_row($r);
    $x = explode(" ", $n[0]);
    $m = $str = '';
    $f = $t = array();
    foreach ($x as $tmp)
    {
      if (strlen($tmp) > strlen($m)) $m = $tmp;
      $f[] = "/($tmp)/i";
      $t[] = '<font color=red>\1</font>';
    }
    $s1  = "SELECT id,board,owner,chrono,title,SUBSTRING(body,LOCATE('$m', body)-50,200) AS xbody ";
    $s2  = "FROM bbs_posts WHERE MATCH(title,body) AGAINST ('$q'";
    $s2 .= (preg_match('/[<>\(\)~\*"+-]/', $q) ? ' IN BOOLEAN MODE' : '');
    $s2 .= ") LIMIT 100"; 
   
    $r = mysql_query("SELECT COUNT(*) $s2");
    $x = mysql_fetch_row($r);
    $x = $x[0];
    $s = $s1 . $s2;
    echo '<div style="border:1px solid red;background-color:#e0e0e0;font-family:tahoma;padding:8px;"><b>The Core SQL Query String:</b><br>' . $s . '</div><br>';
    $r  = mysql_query($s);
    while ($tmp = mysql_fetch_assoc($r))
    {
      if (($pos = strpos($tmp['owner'], '.')) || ($pos = strpos($tmp['owner'], '@')))
        $tmp['owner'] = substr($tmp['owner'],0,$pos).'.';
      $str .= "<li><a href=\"?id=$tmp[id]\" onclick=\"return false;\" style=\"text-decoration:underline;color:blue\" title=\"点击浏览...\">$tmp[title]</a> <small><font color=green>(看板: $tmp[board])</font></small><br>\n";
      $str .= "<small> ... $tmp[xbody] ...</small><br>\n";
      $str .= "<small style=\"color:green;font-family:tahoma;\">Author: <u>$tmp[owner]</u> Date: " . date("Y-m-d H:i", $tmp['chrono']) . "</small>\n";
      $str .= "</li><br><br>\n";
    }
    $f[] = '/\x1b\[.*?m/';
    $t[] = '';
    $str = preg_replace($f, $t, $str);
  } 
  mysql_close();
}
?>
<title>BBS(看板检索: powered by MySQL fulltext+)</title>
<style type="text/css">
body { line-height: 125%; }
</style>
<h2>BBS(看板检索: powered by MySQL fulltext+)</h2>
<form method=get style="margin:0">
<input type=text name=q size=30 value="<?php echo $_GET['q'];?>">
<input type=submit value="Search!">
<small>
(随便输入字符串检索, 还可以用简单的 +/- 哦, 收录约有 140万篇文章)
</small>
</form>
<ol>
<?php echo $str; ?>
</ol>

相 关 文 章
相 关 软 件
 放生
 够爱
 触电
 白狐
 真爱
 天路
 彩虹
 烟火
 日不落
 爱转角
 蓝眼泪
 青花瓷
 老人与海
 边做边爱
 牛仔很忙
 你的选择
 等一分钟
 冰河时代
 我最闪亮
 自由飞翔
 爱死了昨天
 会呼吸的痛
 我们的纪念
 做你的爱人
 爱大了受伤了
 上帝是个女孩
 思念是一种病
 只对你有感觉
 有没有人告诉你
 听着情歌流眼泪
 遇上你是我的缘
 在梵高的星空下
 找个好人就嫁了吧
 下辈子也要找到你
 全世界最伤心的人
 寂寞的时候说爱我
加入收藏留言建议自助友情链接普通友情链接站长的Blog
版权所有   COPYRIGHT 2002-2008 ★IT学习者★ ALL RIGHTS RESERVED.