Sphinx&coreseek实现中文分词索引

栏目: 编程工具 · 发布时间: 5年前

内容简介:Write By CS逍遥剑仙我的主页:GitHub:

Sphinx&coreseek实现中文分词索引

Write By CS逍遥剑仙

我的主页: www.csxiaoyao.com

GitHub: github.com/csxiaoyaojianxian

Email: sunjianfeng@csxiaoyao.com

QQ: 1724338257

1. 简介

众所周知,mysql等数据库的LIKE模糊搜索不支持索引,因此查询效率极低,需要结合第三方索引引擎程序(索引程序)来提高查询性能。开源索引程序有3大类:lucene系(java开发,包括solr和elasticsearch)、sphinx(c++开发,简单高性能)、Xapian(c++开发),其中lucene由于hadoop的原因名气最大,sphinx因为简单可靠,代码结构优良,性能非常好,在国内大型网站中使用最广。sphinx是国外的一款搜索软件,但是本身不支持中文索引,coreseek在sphinx基础上增加了中文分词功能,支持了中文索引。本文主要介绍Sphinx和coreseek的使用。

2. Sphinx使用流程

step1:Sphinx对数据库数据创建索引,使用分词技术分别对单词存储记录id(当数据量大时较费时间)

step2:启动Sphinx服务器

step3:查询程序首先将关键词发送给Sphinx服务器查询,sphinx返回查询结果在原数据库表中的id(主键)

step4:查询程序根据返回的主键id在原数据库中取出相应记录

3. 最佳实践

GitHub: https://github.com/sphinxsearch/sphinx

### ./configure –prefix=/usr/local/sphinx #注意:这里sphinx已经默认支持了mysql
### ./configure --prefix=/usr/local/sphinx --with-mysql=/usr/local/mysql
$ ./configure --prefix=/usr/local/sphinx --with-mysql=/Applications/MAMP/Library
$ make && make install
# 修改配置文件
$ cd /usr/local/sphinx/etc
$ cp sphinx.conf.dist sphinx.conf
$ vim sphinx.conf # 修改配置
# 导入etc下的测试数据
$ mysql -uroot -p test < example.sql
# 建立索引文件
$ bin/indexer -c etc/sphinx.conf
# 运行sphinx
$ bin/searchd
# 运行 php 测试
$ php api/test.php -h localhost

4. coreseek安装

coreseek在Sphinx基础上支持了中文扩展,下载coreseek安装包解压后得到两个目录csft和mmseg,csft-xxx相当于sphinx安装目录,mmseg-xxx为中文分词安装包

# 安装中文分词库 cd mmseg-xxx,可能需要额外按照automake
$ ./configure --prefix=/usr/local/mmseg/
# 安装coreseek cd csft-xxx
$ ./configure --prefix=/usr/local/coreseek --with-mysql=/usr/local/mysql --with-mmseg-includes=/usr/local/mmseg/include/mmseg/ --with-mmseg-libs=/usr/local/mmseg/lib/
$ make && make install

5. 相关配置

5.1 配置文件格式

sphinx.conf的内容组成格式为:

source <源名称1>{
	…
}
index <索引名称1>{
	source = <源名称1>
	…
}
source <源名称2>{
	…
}
index <索引名称2>{
	source = <源名称2>
	…
}
indexer{
	…
}
searchd{
	…
}

5.2 建立数据源(需建立索引的数据)

# 配置格式参考,默认情况下修改数据库用户名和密码即可
source user_source_1
{
    type                    = mysql             // 数据库类型
    sql_host                = localhost         // 所连接的 ip
    sql_user                = root              // 数据库用户名
    sql_pass                = root              // 数据库密码
    sql_db                  = test              // 数据库名称
    sql_port                = 3306              // 数据库端口
    sql_query_pre           = SET NAMES utf8    // 数据库预查询
    # 主查询,执行结果作为数据源
    # 注意:
    # 1. 取出的数据中,必须有id(若无名称为id的字段,可以使用别名),id为主键
    # 2. id后面的字段创建索引
    sql_query               = SELECT id,name,age FROM user
	...
}

5.3 创建索引

index user_index_1
{
	# 对应创建的数据源
    source					= user_source_1
    # 指定索引文件存放路径
    path					= xxxxx/var/data/xxx
    ...
    # 中文分词配置
    charset_dispath			= xxxxx/etc/
    charset_type			= zh_cn.utf-8
}

5.4 配置服务器

searchd
{
	...
	# 指定进程文件、日志文件、查询日志文件的位置
	pid_file				= xxx
	log						= xxx
	query_log				= xxx
}

6. 创建索引并启动服务器

使用 bin 下的 indexer 创建索引

$ indexer -c <配置文件> --all | <索引文件名>

使用searchd启动sphinx服务器

7. PHP应用: 关键词查询并高亮显示

<?php
    header("content-type:text/html;charset=utf8");
    require 'sphinxapi.php';
    // 创建对象
    $sc = new SphinxClient();
    // 连接服务器
    $sc->setServer('localhost','9312');
    // 执行查询 query('查询关键词','使用索引')
    $keywords = 'CS逍遥剑仙';
    $indexName = 'user_index_1';
    $res = $sc->query($keywords,$indexName);
    // 设置查询数量,(offset limit)
    $sc->setLimits(20, 5);
    // 返回结果
    $ids = $res['matches'];
    $id = implode(',', array_keys($ids));
    // 连接 mysql 服务器
    $conn = mysql_connect('localhost','root','root');
    mysql_query('use php');
    mysql_query('set names utf8');
    mysql_query("select id,name,from user where id in($id)");
    $data = array();
    while($row = mysql_fetch_assoc($result)){
        $data[] = $row;
    }
    // 输出数据
    foreach($data as $v){
    	// param1: 输出的数据
    	// param2: 索引名称
    	// param3: 关键词
    	// param4: 设置关键词显示的样式
    	// return: 索引数组
        $v = $sc->buildExcerpts($v,$indexName,$keywords,array(
        	'before_match'=>'<font style="color:#f00">',
        	'after_match'=>'</font>'
        ));
        echo $v[1].'<br/>'.$v[2].'<hr>';
    }
    print_r($data);
?>

8. Sphinx匹配模式

提供了5种模式:

SPH_MATCH_ALL: (默认)匹配所有查询词,会对查询关键词分词,查询结果必须同时包含所有关键词

SPH_MATCH_ANY: 查询关键词分词,查询结果匹配其中任意一个即可

SPH_MATCH_PHRASE: 查询关键词不分词,查询结果必须严格匹配整个查询关键词

SPH_MATCH_EXTENDED: 支持扩展语法,支持@字段查询,如查询title包含abc,content包含bcd:'@title abc @content bcd'

SPH_MATCH_BOOLEAN: 与/或/非/分组,& / or / ! / ()

<?php
    ...
    $keywords = 'CS逍遥剑仙';
    $indexName = 'user_index_1';
    // 设置匹配模式
    $sc->setMatchMode(SPH_MATCH_ALL);
    $res = $sc->query($keywords,$indexName);
    ...

9. 增量索引

主表数据增加需要增加索引,如果数据量大,直接重建索引会很慢,可通过对增加的数据单独建立索引,再把建立的索引合并到主索引。

9.1 确定新增数据的方案

(1) 创建一张表,记录数据的最大id

mysql> create table t(id int)engine myisam charset utf8;
mysql> insert into t values(10000)

# 增量索引配置
source src_zl 
{
    ...
    sql_query			= select id,name from user where id>(select id from t)
    # 创建增量索引时更新表中最大id
    sql_query_post		= update a set id = (select max(id) from user)
}
index index_zl 
{
    source				= src_zl
    path				= /usr/local/sphinx/var/data/src_zl
    ...
}

(2) 创建增量索引,rotate强制执行

$ bin/indexer -c /usr/local/sphinx/etc/sphinx.conf index_zl --rotate

(3) 增量索引合入主索引

$ bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --merge user_index_1 index_zl --rotate

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

RESTful Web Services Cookbook

RESTful Web Services Cookbook

Subbu Allamaraju / Yahoo Press / 2010-3-11 / USD 39.99

While the REST design philosophy has captured the imagination of web and enterprise developers alike, using this approach to develop real web services is no picnic. This cookbook includes more than 10......一起来看看 《RESTful Web Services Cookbook》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试