首页 > web > php

sphinx+scws+php+mysql建立全文中文分词搜索

admin2019--06-21共有1245人围观
简介sphinx+scws+php+mysql建立全文中文分词搜索

环境版本php7.2+mysql5+.7+sphinx3.0.1+scws1.2.3,建立全文分词搜索

PHP和mysql的我就不说了。

sphinx的安装,百度的都是2.x版本的,编译安装,和一般安装差不多,就不累赘了。我安装的3.0.1有些许不同,这里讲一下。

到官网下载对应安装包http://sphinxsearch.com/downloads/current/

windows安装,直接下载安装包,解压出来,然后在目录bin文件夹中,ctrl+右键打开CMD命令窗口,

searchd --install --config e:\Sphinx\sphinx.conf --servicename SphinxSearch

安装,并添加到windows服务中,启动服务即可。

linux安装

wget http://sphinxsearch.com/files/sphinx-3.0.1-7fec4f6-linux-amd64.tar.gz
tar zxvf sphinx-3.0.1-7fec4f6-linux-amd64.tar.gz

同样下载安装包,解压成sphinx-3.0.1,但是这里不用编译安装了,直接

/home/download/sphinx-3.0.1/bin/searchd --config /home/download/sphinx-3.0.1/etc/sphinx.conf

就启动服务了,记住前面加上自己的目录路径。

但是我服务器启动的时候出现了/lib64/libc.so.6: version `GLIBC_2.14' not found错误,上网查询是glibc版本低了 ,是2.12的,需要升级。但是glibc现在有2.26,升级跨度大的话,可能会出现兼容问题,导致linux其他服务可能无法使用,所以保守安装2.14版的

 wget http://ftp.gnu.org/gnu/libc/glibc-2.14.tar.gz
 wget http://ftp.gnu.org/gnu/libc/glibc-ports-2.14.tar.gz
 tar -xvf  glibc-2.14.tar.gz
  
tar -xvf  glibc-ports-2.14.tar.gz
  
mv glibc-ports-2.14 glibc-2.14/ports
  
mkdir glibc-build-2.14
  
cd glibc-build-2.14
../glibc-2.14/configure  --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin;
 
make;make install
 
cp /glibc-build-2.14/libc.so /lib64/libc-2.14.so
rm -rf /lib64/libc.so.6
LD_PRELOAD=/lib64/libc-2.14.so ln -s /lib64/libc-2.14.so  /lib64/libc.so.6

这个时候就可以启动sphinx的searchd服务了。PHP的SDK就是sphinx-3.0.1/api/sphinxapi.php,把它复制到项目中去(我的是extend/sphinx),同级建立sphinxsearch.php文件

namespace sphinx;
require ( "sphinxapi.php" );
class sphinxsearch{
    protected $host;
    protected $user;
    protected $passwd;
    protected $port;
    protected $sport;
    protected $db;
    protected $charset = 'utf8';
    protected $error;
    protected $conn = null; // 准备用来存储连接的资源
 
    function __construct($h='127.0.0.1', $port=9306 ,$sport = 9312, $u='root',$pwd='root') {
        $this->host = $h;
        $this->user = $u;
        $this->passwd = $pwd;
        $this->port = $port;
        $this->sport = $sport;
        $this->connect();
    }
 
    public function connect() {
        if($this->conn = mysqli_connect($this->host . ':' . $this->port)) {
            return true;
        } else {
            return false;
        }
    }
 
    public function query($sql) {
        $rs = mysqli_query($this->conn,$sql);
        if(!$rs) {
            $this->error = mysqli_error($this->conn);
            //$this->log($this->error);
            return false;
        }
        return $rs;
    }
    //创建Sphinx实时索引:一条索引记录
   public function createRTIndex( $indexName , $attrs ){
      $fields = '';
      $vals = '';
      foreach($attrs as $k => $v ){
         $fields .= $k . ',';
         $vals .= "'$v'" . ',';
      }
      $fields = trim( $fields , ',');
      $vals = trim( $vals , ',' );
      if( empty($fields ) || empty($vals) )
         return false;
      $sql = "insert into $indexName($fields) values($vals)";
      return $this->query($sql);
   }
 
   //搜索
   public function search( $key , $indexName = '*' ,$offset = 0 , $pagesize = 30  ,$attr=[]){
      $cl = new \SphinxClient();
      $cl->SetServer( $this->host, $this->sport );
      $cl->SetConnectTimeout ( 3 );
      $cl->SetArrayResult ( true );
      $cl->SetMatchMode ( SPH_MATCH_EXTENDED2);
      $res = $cl->Query ( $key , $indexName );
      return $res;
   }
    public function deleteItem($indexName,$id){
        $res=$this->query("DELETE FROM $indexName WHERE id=$id");
        return $res;
    }
 
    public function getItem($indexName,$id){
        $res=$this->getRow("SELECT * FROM $indexName WHERE id=$id");
        return $res;
    }
 
    public function getTotal($indexName){
        $res=$this->getRow("SELECT count(*) FROM $indexName");
        return $res;
    }
 
    public function deleteAll($indexName){
        $res=$this->query("DELETE FROM $indexName");
        return $res;
    }
}

是不是很熟悉?没错 ,直接mysql的用法,直接使用就行了。

因为我用在搜索,所以我用的RT实时索引,需要先写好配置,然后启动

#RT实时索引配置
 
#RT实时索引定义,搜索建议实时索引
index moviesearch
{
    type                    = rt
    path            = e:/sphinx/data/moviesearch #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    docinfo            = extern
    mlock            = 0
    morphology        = none
    min_word_len        = 1
    html_strip                = 0
    enable_star = 1
    #min_prefix_len = 3
    min_infix_len = 1
    #infix_fields = PY1,PY2
 
    # 编码
    charset_type = utf-8
    # 指定utf-8的编码表
    charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
    # 简单分词,只支持0和1,如果要搜索中文,请指定为1
    ngram_len = 1
    # 需要分词的字符,如果要搜索中文,去掉前面的注释
    ngram_chars   = U+3000..U+2FA1F
     
    #字段设置顺序:field, uint, bigint, float, timestamp, string;顺序不可颠倒,否则产生混乱
    #使用后,不可更改字段设置,除非删除所有索引文件重新建立,否则产生混乱
 
    #文档编号字段
    #id                                               #系统自动处理
    #全文索引字段
    rt_field                  = post_title      #全文索引字段
    rt_field                  = post_alias      #全文索引字段
    rt_field                  = post_excerpt      #全文索引字段
    rt_field                  = stars      #全文索引字段
    rt_field                  = directors      #全文索引字段
     
    #属性字段
     
    rt_attr_uint              = v_id
    rt_attr_uint            = post_status
    rt_attr_uint              = is_end
    rt_attr_uint              = area
    rt_attr_uint              = yeas
    rt_attr_uint              = is_cai
    rt_attr_string          = post_title
    rt_attr_string          = post_alias
    rt_attr_string          = post_excerpt
    rt_attr_string          = stars
    rt_attr_string          = directors
    rt_attr_string          = more
    rt_attr_string          = numbers
 
    #RT实时索引内存设置
    rt_mem_limit = 100M
}
#searchd服务定义
searchd
{
    workers             =    threads
    listen                  =   9312
    listen                  = localhost:9306:mysql41    #MySQL 协议支持与SphinxQL
    read_timeout        = 5
    max_children        = 30
    max_matches            = 1000
    seamless_rotate        = 0
    preopen_indexes        = 0
    unlink_old            = 1
    pid_file = e:/sphinx/data/moviesearch.pid  #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    log = e:/sphinx/moviesearch.log        #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    query_log = e:/sphinx/data/query_rtindex.log #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    binlog_path = e:/sphinx/data       #请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...
    binlog_flush = 2
    binlog_max_log_size = 100M
}

好了,下面是SCWS分词:

官方安装文档

windows安装http://www.xunsearch.com/scws/docs.php#instdll

linux安装http://www.xunsearch.com/scws/docs.php#instscws

下载PHP SDK  [立即下载:pscws4-20081221.tar.bz2 (18.1KB)] [说明文档]

解压后,复制pscws4,class.php和xdb_r.class.php文件到项目中/extend/scws中,重命名为pscws.php和xdb_r.php

修改pscws.php文件

namespace scws;
require ( 'xdb_r.php');
class pscws{}
function __construct($charset) { $this->PSCWS4($charset); }
$xdb = new \XDB_R();
function set_dict($fpath='dict.utf8.xdb')
{
   $xdb = new \XDB_R();
   if (!$xdb->Open(dirname(__FILE__) . '/etc/'.$fpath)) return false;
   $this->_xd = $xdb;
}
function set_rule($fpath='rules.utf8.ini')
{
   $this->_rule_load(dirname(__FILE__) . '/etc/'.$fpath);
}

复制rules.ini、rules.utf8.ini和rules_cht.utf8.ini到/extend/scws/etc中

下载XDB 词典文件

 [简体中文(GBK) (3.84MB,28万词,2016/02/24更新)]
 [简体中文(UTF-8) (3.9MB,28万词,2016/02/24更新)] 
 [繁体中文(UTF-8) (1.21MB,10万词)]

复制文件到/extend/scws/etc中。


修改php.ini

extension = scws.so
scws.default.charset = gbk
scws.default.fpath = /usr/local/scws/etc

然后使用:

$pscws=new pscws('utf8');
$pscws->set_dict();
$pscws->set_rule();
$pscws->set_ignore(true);
$pscws->set_multi(false);
$pscws->set_duality(false);
$pscws->send_text($k);
$words = $pscws->get_result();
$pscws->close();
$tags = array();
foreach ($words as $val) {
    $tags[] = '('.$val['word'].')';
}
$k=implode('|', $tags);
$sp=new sphinxsearch();
$res=$sp->search($k,'moviesearch');


下一篇 >: sphinx分词精准搜索

文章评论

评论列表(0)

发表评论 取消回复

微信公众账号

微信扫一扫加关注