IT学习者 | 文章大全 | 技术文档 | 桌面壁纸 | 网络电台 | 成语 | 歇后语 | 站长导航 | 下载 | 周公解梦 | 生日密码 | 站长助手 | Flash | IP地址查询
 您现在的位置: 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-2009 ★IT学习者★ ALL RIGHTS RESERVED.