zoukankan      html  css  js  c++  java
  • 基于MySQL数据库的UTF8中文网站全文检索的实现

    简介:这是基于MySQL数据库的UTF8中文网站全文检索的实现的详细页面,介绍了和php,有关的知识、技巧、经验,和一些php源码等。

    class='pingjiaF' frameborder='0' src='http://biancheng.dnbcw.info/pingjia.php?id=323145' scrolling='no'>

    现在的互联网上,很多网站都提供了全文搜索功能,浏览者可以通过输入关键字或者是短语来搜索特定的资料。在PHP+MySQL构架的网站中,通常的做法是通过SELECT查询的Like语句来进行搜索,这一办法存在搜索不够精确、以及效率非常低下的缺点。比如对一个有十几万条记录数据表的TEXT字段进行LIKE操作,可能会花费上近10秒钟左右,这对网站的浏览者来说是一个非常糟糕的使用体验。如何在海量的数据中能够快速的进行全文检索呢?MySQL提供了一个全文索引功能,也就是把字段设置上FULLTEXT索引属性,然后通过SELECT的MATCH AGAINST语句进行查找。

    我们开发的一个纯英文站点TouchUs - The Global Yellow Pages & Business Directory(www.touchus.org)就是利用MySQL的这一功能,实现了对十多万条数据的平均全文检索时间小于0.5秒。但是在开发TouchUs的中文网站——城市黄页网时(www.city39.cn),碰到了新的问题。原来英文排版时词和词之间是通过空格区分的,FULLText可以完全支持,但是对中文或者是东亚文字就没有这么简单了,因为中文的词和词之间并没有明显的分隔,所以MySQL不支持中文字符的全文检索。

    如何让MySQL也能支持中文的全文检索呢?偶然间产生了一个思路,那就是能不能在中文分词后,通过对中文进行编码转化成英文字符,这样就在中英文间建立一个特定的联系,然后再进行全文检索,这样不就实现了中文的全文索引了吗?经过试验,答案是肯定的。下面是在城市黄页网中实现的具体过程:

    1. 建立一个单独的索引表,比如对应members表,我们建立一个members_index表。

    用户信息表(members)                    用户信息全文索引表(members_index)
    User_id                                              user_id
    User_name                                       index_intro
    User_introduction                                    
     在members_index表的index_intro中加入fulltext索引。

    2. 对用户信息表(members)的User_introduction字段内容进行中文分词处理

    中文分词的处理过程,可以参考简易中文分词系统http://www.ftphp.com/scws/,在城市黄页网中,我们采用了scws的PHP扩展模块方式来实现中文分词。scws的php扩展模块安装非常简单,只需简单编译配置后即可使用。在具体的php代码中,我们写了如下的函数来实现分词后将分词结果用空格进行连接。

    //中文分词函数
    function str_fc($str) {
     $so = scws_new();
     $so->set_charset('utf8');
     // 这里没有调用 set_dict 和 set_rule 系统会自动试调用 ini 中指定路径下的词典和规则文件
     $so->send_text($str);
     while ($tmp = $so->get_result())
     {
      foreach (  $tmp as $ss ){
       $s = trim($ss[word]);
       if ( $s )
        $mystr .= trim($ss[word]) . " ";
        //echo urlencode(trim($ss[word])) . " ";
      }
     }
     return $mystr;
    }
    该函数返回就是用空格连接的分词结果。

    3. 对分词结果进行编码,可以采用多种编码方式,比如base64编码、urlencode编码、汉字转拼音等,对gb2312甚至可以采用区位码编码方式。考虑到存储空间以及便利性,我们采用了PHP的urlencode编码方式。需要注意的是,在编码前,我们可以去掉重复的分词来节约存储空间,编码后要去掉编码结果中的%符号,因为urlencode采用RFC 1738进行编码,会产生很多%,而%在MySQL是通配符。下面是编码过程用到的PHP代码

    $data = str_fc($data);  //中文分词
     $data = array_filter(explode(" ",$data)); //删除数组空项
     $data = array_flip(array_flip($data));  //删除重复项
     
     //对分词结果进行urlcode编码
     foreach (  $data as $ss ) {
      if (strlen($ss)>1 )
      $data_code .= str_replace("%","",urlencode($ss)) . " ";
     }
    这里的$data_code就是编码后的结果。把编码结果根据user_id存入用户信息全文索
    引表(members_index)

    4. 在进行搜索处理时,首先对用户输入的关键字进行同样的分词编码处理,然后通过MySQL的SELECT的MATCH  AGAINST语句进行全文快速检索,根据检索结的user_id即可调用用户信息表(members)中的原始数据进行显示,而没有必要进行一次解码重组。

    以上MySQL UTF8中文全文检索方法,目前在我们的2个中文网站——城市黄页网(www.city39.cn)和企业供求信息网(www.myglobalmarket.cn)中运行良好,平均检索时间均小于0.5秒。

    “基于MySQL数据库的UTF8中文网站全文检索的实现”的更多相关文章 》

    爱J2EE关注Java迈克尔杰克逊视频站JSON在线工具

    http://biancheng.dnbcw.info/php/323145.html pageNo:16
  • 相关阅读:
    【codevs1227】方格取数2(最大流费最大流-模板
    【ZJOI2008】【BZOJ1033】杀蚂蚁(占坑待填
    python基础学习1-流程控制和判断
    python基础学习1-变量定义赋值,屏幕输入输出
    Jzoj5237 最长公共子序列
    Jzoj5236 利普希茨
    [置顶] 欢迎使用CSDN-markdown编辑器
    Jzoj5235 好的排列
    Jzoj5234 外星人的路径
    Jzoj5231 序列问题
  • 原文地址:https://www.cnblogs.com/ooooo/p/2255914.html
Copyright © 2011-2022 走看看