sphinx

来源:互联网 发布:linux 格式化ext4 编辑:程序博客网 时间:2024/05/12 07:53

一、sphinx简介

1、为什么要用sphinx

mysql数据库中,对于如下sql语句,select * from xxx where like xxx ‘%xxx’(%开头的like查询),无法使用到任何索引优化,导致如果数据量非常大,查询速度会非常慢。而这种sql语句在很多功能中都要用到,如根据歌词查询歌曲,根据剧情查询电影等。如果要加快查询只能使用第三方软件,sphinx和lucence。

mysql中也提供了全文索引的功能,但是有两个问题:(1)只有myisam引擎支持(2)对中文支持不好。不过现在最新的mysql5.6版本中的innodb1.2的版本也同样支持全文索引。

2sphinx介绍?

中文名:全文索引引擎。只支持英文和俄文。但是只要有相应的语言包也可支持任何语言。国内有一团队在sphinx基础上封装了一个带中文包的软件:coreseek

 

3、使用原理

1)先创建数据源,

2)根据数据源创建索引,使用分词技术。

3php把查询的关键词给sphinx服务器,sphinx根据关键词查找到关键字在mysql表里面的记录的id.sphinxid返回给php查询端

4php根据返回的id,查询mysql服务器,

原理图:

 

 

二、安装使用

1、下载软件,进行解压,

从 http://www.sphinxsearch.com 官网下载,支持中文分词的可以

从 http://www.coreseek.com下载

 

解压后拷贝到指定的目录,一般和其他的环境程序在同一级目录(便于管理)

 

2、拷贝配置文件,

etc目录下面的csft_mysql.conf文件拷贝到上一级目录,并改名为sphinx.conf

 

 

三、具体的使用配置

1配置数据源和索引,并指定服务器信息

主要是配置sphinx.conf配置文件

1)配置数据源(被查询的数据,就是sql语句执行的结果)

配置语法:

source 数据源名称{ }

#源定义

source movie

{

    #连接数据库的相关参数

    type = mysql

    sql_host = localhost

    sql_user = root

    sql_pass = root

    sql_db = test

    sql_port = 3306

    #设置预查询语句

    sql_query_pre = SET NAMES utf8

    #设置sel语句

    sql_query = select id,title,description from movie

    #sql_query第一列id需为整数

    #titlecontent作为字符串/文本字段,被全文索引

    sql_attr_uint = group_id           #SQL读取到的值必须为整数

    sql_attr_timestamp = date_added   #SQL读取到的值必须为整数,作为时间属性

    sql_query_info_pre =  SET NAMES utf8   #命令行查询时,设置正确的字符集

    sql_query_info =  SELECT * FROM documents WHERE id=$id #命令行查询时,从数据库读取原始数据信息

}

注意:在一个配置文件中,可以配置多个数据源。

 

2)配置数据源生成的索引文件存放的位置。

语法:index 索引的名字{

注意:该索引必须与一个数据源相对应, 

#index定义索引

index movie#可随意命名

{

    source movie#对应的source名称

    #生成的索引文件

Path = F:/server/sphinx/var/data/movie 

#movie为要生成的索引文件,可随意命名,请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

    docinfo = extern

    mlock = 0

    morphology = none

    min_word_len= 1

    html_strip = 0

    #中文分词配置,详情请查看:http://www.coreseek.cn/products-install/coreseek_mmseg/

    #charset_dictpath = /usr/local/mmseg3/etc/ #BSDLinux环境下设置,/符号结尾

    #语言包的路径

charset_dictpath  = F:/server/sphinx/etc/    

#Windows环境下设置,/符号结尾,最好给出绝对路径,例如:C:/usr/local/coreseek/etc/...

    charset_type = zh_cn.utf-8

}

 

(3)配置sphinx服务器的信息 

#searchd服务定义

searchd

{

    listen = 9312

    read_timeout = 5

    max_children = 30

    max_matches = 1000

    seamless_rotate = 0

    preopen_indexes = 0

    unlink_old = 1

    #指定进程文件、日志文件、查询日志文件的路径

pid_file = F:/server/sphinx/var/log/searchd_mysql.pid  

#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

log = F:/server/sphinx/var/log/searchd_mysql.log        

#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

query_log = F:/server/sphinx/var/log/query_mysql.log 

#请修改为实际使用的绝对路径,例如:/usr/local/coreseek/var/...

}

 

2、创建索引

对应index movie里面的Path = F:/server/sphinx/var/data/movie 

 

执行sphinx下的程序

语法:indexer.exe  –c  配置文件(全路径) --all | 索引的名字

--all:为配置文件中所有的索引创建索引文件。也可以使用索引的名字只为某一个索引创建索引文件。

 

(1)以管理员的方式打开cmd窗口。执行indexer.exe命令

C:\Users\Administrator>  f:

F:\>  cd /server/sphinx/bin/

F:\server\sphinx\bin> indexer -c f:/server/sphinx/sphinx.conf movie

2)查看创建的索引文件:f:/server/sphinx/var/data


3、启动sphinx的服务器

对应配置文件sphinx.conf配置文件中的searchd配置

 

(1)把sphinx软件安装为一个系统一个服务。 

语法:searchd.exe –c 配置文件 --install 

F:\server\sphinx\bin> searchd -c f:/server/sphinx/sphinx.conf --install

可以通过searchd --help 查看帮助

 (2)启动该服务

F:\server\sphinx\bin>  net start searchd

查看端口是否启动:9312默认端口)

 

4、通过php查询使用。

1)在php使用中,需要一个sphinx的一个接口文件:f:/server/sphinx/api/sphinxapi.php 

(2)代码如下:

header("content-type:text/html;charset=utf-8");

//引入api文件接口文件

require "/api/sphinxapi.php";

//生成客户端

$sc = new SphinxClient();

//设置服务器

$id = $sc -> setServer("localhost",9312);//为什么返回NULL

$keyword = '电影';

$indexname = 'movie';

//query('查询的关键词','索引文件的名称')

$res = $sc -> query($keyword,$indexname);

echo "<pre>";

var_dump($res);

-- 到浏览器查看结果


继续完善以上代码:

header("content-type:text/html;charset=utf-8");

//引入api文件接口文件

require "/api/sphinxapi.php";

//生成客户端

$sc = new SphinxClient();

//设置服务器

$sc -> setServer("localhost",9312); //为什么返回NULL

$keyword = '电影';

$indexname = 'movie';

//query('查询的关键词','索引文件的名称')

$res = $sc -> query($keyword,$indexname);

$ids = $res['matches']; //是一个二维数组,每一个元素都是以id为下标的索引数组

$id = array_keys($ids); //获取$ids里面的所有下标

$id = implode(',',$id);


//连接mysql

mysql_connect("localhost","root","root");

mysql_query("set names utf8");

mysql_query("use test");

$sql = "select id,title,description from movie where id in($id)";

$res = mysql_query($sql); 

while($row = mysql_fetch_assoc($res)){

echo $row['title']."<br/>".$row['description']."<hr/>";

}

 

四、SPHINX的匹配模式

1SPH_MATCH_ALL 

完全匹配所有的词:只要内容中包含需要匹配的词,不论是否连贯,都能被匹配到

如“冬天  的   雪”,并不会匹配 “我爱冬天”,

但可以匹配 “的朋友,爱冬天,和雪”

因为“冬天的雪” 被分成 “冬天”,“的”,“雪”三个词,匹配条件是同时包含

这三个词,“我爱冬天”里只包含一个“冬天”

2、SPH_MATCH_PHRASE

必须匹配整个短语:完全精确匹配需要匹配的词

如“冬天的雪”,不会匹配 “的朋友,爱冬天,和雪”,虽然都包含同样的 

需要严格匹配不再健忘,只匹配“冬天的雪”

 

3、SPH_MATCH_ANY

匹配任意一个词:只要内容中包含要匹配的词中的任意一个词,都会被匹配到

如“冬天   的     雪”,并会匹配 “我爱冬天

"冬天的雪“ -》 冬天“ ”“ ”

因为“我爱冬天”里有一个“冬天”相匹配。

 

4、SPH_MATCH_EXTENDED

$sc -> setMatchMode(SPH_MATCH_EXTENDED);

支持一些扩展的语法:

支持 @字段 查询

如,查询title包含 abc , content 包含 bcd的:

'@title abc @content bcd'

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

如:hello | world

查询“手机”,或“冬天”,:


五、查找到的关键词添加样式显示

主要使用:buildExcerpts : 创建文档摘要,对关键词添加样式显示

完整代码:主要修改红色部分代码

header("content-type:text/html;charset=utf-8");

//引入api文件接口文件

require "/api/sphinxapi.php";

//生成客户端

$sc = new SphinxClient();

//设置服务器

$sc -> setServer("localhost",9312); //为什么返回NULL

$keyword = '电影';

$indexname = 'movie';

//query('查询的关键词','索引文件的名称')

$res = $sc -> query($keyword,$indexname);

$ids = $res['matches']; //是一个二维数组,每一个元素都是以id为下标的索引数组

$id = array_keys($ids); //获取$ids里面的所有下标

$id = implode(',',$id);

 

//连接mysql

mysql_connect("localhost","root","root");

mysql_query("set names utf8");

mysql_query("use test");

$sql = "select id,title,description from movie where id in($id)";

$res = mysql_query($sql); 

while($row = mysql_fetch_assoc($res)){

$r = $sc -> buildExcerpts($row,$indexname,$keyword,array(

'before_match' => "<font color='red'>",

'after_match' => "</font>"

)); 

echo $r[1]."<br/>".$r[2]."<hr/>";

}

六、增量索引

1、增量索引的原理:

 

2、实现方式

1)新建一张表,记录一下上次已经创建好索引的最后一条记录的id 

2)当索引时,然后从数据库中取出所有大于id的数据,这些就是新的数据然后创建一个小的索引文件。

3)把增量这部分数据生成的小的索引合并到主索引文件上去。

4)把最后一条记录的id更新到第一步创建的表中。

 

3、实现步骤:

1)创建一个表,用于记录创建好索引的最后一条记录的id

mysql> use test

mysql> create table a(id int);

mysql> set names gbk;

mysql> insert into a value(0);

mysql> select * from a;

(2)修改sphinx的配置文件,主索引的数据源

创建完主索引之后把最后一条记录的id存放到a表里面

 sql_query_post = update a set id = (select max(id) from movie)


(3)创建增量索引的数据源,以及增量索引文件存储的位置

① 复制源定义,修改里面的sql语句

 sql_query = select id,title,description from movie where id>(select id from a)


② 一个源对应一个索引,所以还要复制一份主索引,并且修改源和索引路径名

 

 

4)把sphinx的服务器停止,并删除原来的索引文件。

创建主索引。

F:\server\sphinx\bin>net stop searchd

F:\server\sphinx\bin>indexer -c f:/server/sphinx/sphinx.conf movie

F:\server\sphinx\bin>net start searchd

-- 查看a表里面是否记录最大的id


5)启动sphinx的服务器,进行查询测试

 

(6)插入数据:添加一部新的电影

 

7)创建增量索引,

F:\server\sphinx\bin>indexer -c f:/server/sphinx/sphinx.conf movie_zl --rotate

 

8)把创建的增量索引合并到主索引里面。

使用的语法: indexer  -c  配置文件   --merge   主索引文件  增量索引文件  --rotate 

--rotate 强制合并,可以不关闭sphinx服务的情况下合并。

F:\server\sphinx\bin>indexer -c f:/server/sphinx/sphinx.conf --merge movie movie_zl --rotate

 

 

7、报错

1)查不到可能会报下面错误

 

(2)强制执行命令:在命令后面添加  --rotate

 

0 0