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的版本也同样支持全文索引。
2、sphinx介绍?
中文名:全文索引引擎。只支持英文和俄文。但是只要有相应的语言包也可支持任何语言。国内有一团队在sphinx基础上封装了一个带中文包的软件:coreseek。
3、使用原理
(1)先创建数据源,
(2)根据数据源创建索引,使用分词技术。
(3)php把查询的关键词给sphinx服务器,sphinx根据关键词查找到关键字在mysql表里面的记录的id.sphinx把id返回给php查询端
(4)php根据返回的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需为整数
#title、content作为字符串/文本字段,被全文索引
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/ #BSD、Linux环境下设置,/符号结尾
#语言包的路径
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的匹配模式
1、SPH_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'
5、SPH_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
- sphinx
- sphinx
- sphinx
- sphinx
- Sphinx
- Sphinx
- Sphinx
- sphinx
- sphinx
- sphinx
- sphinx
- Sphinx
- sphinx
- Sphinx
- sphinx
- sphinx
- sphinx简析
- Sphinx-4
- Linux配置端口为80
- iOS-关于页面跳转时全局变量赋值不到的问题
- android使用https安全连接
- 最新版SDWebImage的使用
- playframework
- sphinx
- Javascript的继承
- Git如何使用远程仓库
- 熊猫阿波的故事及C++保留小数点的问题
- Maven和Eclipse集成和构建多模块Maven项目
- 分支提交的冲突问题
- 分支管理问题
- 济宁惠普第一个文章
- 最新iwebshop与ucenter整合成功方法及bug处理