Sphinx
一、了解Sphinx
1、为什么要用Sphinx
原因1:因为MySQL不支持中文全文索引、like语句查询满
原因2:sphinx支持中文分词(我 喜欢 php)
2、什么是Sphinx
由俄罗斯人开发的一个基于SQL的、高性能的全文检索软件,用于替代MySQL全文检索。
3、Sphinx的特性
1)特性
高速的建立索引(峰值性能达10M/s)
高性能的搜索(在2-4G的文本数据上,平均每次检索时间小于0.1秒)
可处理海量数据
2)优势
Sphinx单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速
度为0.x秒(毫秒级)。
Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000
万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。
创建索引必须关闭服务
4、Sphinx使用流程
- 步骤1:sphinx去mysql中提取指定字段的关键词出现频率和位置按照词库的顺序归纳
- 步骤2:php根据用户搜索的关键词去sphinx中匹配,获取对应的数据id(编号)
- 步骤3:php根据检索的id去MySQL中查询具体数据
二、安装Sphinx
1、概念
1)什么是Coreseek
Coreseek 是一款中文全文检索/搜索软件,基于Sphinx研发并独立发布,专攻
中文搜索和信息处理领域,适用于行业/垂直搜索、论坛/站内搜索、数据库
搜索、文档/文献检索、信息检索、数据挖掘等应用场景。
简单概括:中文版的sphinx
2)Coreseek和sphinx的关系?
sphinx默认只支持英文和俄文,但是它提供了一种方式可以支持任意一种语言,但是需要自己写相关语言语言词库。
Coreseek是在sphinx的基本上添加了中文词库的二次开发。
简单概括:
sphinx不支持中文,但是开发作者提供了接口,coreseek就基于整个接口开发的。
3)下载地址
Sphinx官网:http://www.sphinxsearch.com
coreseek官网:http://www.coreseek.com (版本:Coreseek 3.2.14)
2、安装Coreseek
■ 安装包(绿色版)目录文件介绍
- bin\indexer.exe 创建索引文件
- bin\searchd.exe 服务端(后期php操作服务器必须启动)
- bin\search.exe 客户端(学习时测试使用,注DOS窗口测试编码gbk)
- ext\csft_mysql.conf 配置文件(声明索引和索引来源)
1)安装
安装目录不能有空格特殊符号或中文
配置Sphinx(重要)
- 步骤1:将etc/csft_mysql.conf复制并更名为sphinx.conf
- 步骤2:打开shpinx.conf修改内容如下
#数据源:数据来源定义(数据库信息、数据源SQL语句)
source music
{
#下面是sql数据库特有的端口,用户名,密码,数据库名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
#sql_query属性:取出要创建索引的数据
#要求1:SELECT的第一个字段必须是主键、
#要求2:第一个字段的名字(别名)必须是id
#要求3:其他的字段就是要创建索引的字段
#需 求:为歌曲表中的title和content字段创建索引
sql_query = SELECT id, title, author, content FROM music
#命令行查询时,设置正确的字符集
sql_query_info_pre = SET NAMES utf8
#命令行查询时,从数据库读取原始数据信息
sql_query_info = SELECT * FROM music WHERE id=$id
}
#索引的定义(索引文件存放的位置,索引文件的名字)
#每个index对应一个数据源,用来定义这个数据源生成的索引文件的信息
index music
{
#该索引对应哪个数据源
source = music
#索引文件存放的目录和名字(存到E:/sphinx/var/data/目录下,索引文件的名字是music)
path = E:/sphinx/var/data/music
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
#词库文件所在的目录
charset_dictpath = E:/sphinx/etc/
#字符集编码类型,可以为:(sbcs,utf-8,zh_cn.utf-8,zh_ch.gbk,zh_ch.big5)
charset_type = zh_cn.utf-8
}
#全局index定义
indexer
{
#建立索引的时候,索引内存限制
mem_limit = 128M
}
#searchd服务定义
searchd
{
listen = 9312
read_timeout = 5
max_children = 30
max_matches = 1000
seamless_rotate = 0
preopen_indexes = 0
unlink_old = 1
# 进程id文件
pid_file = E:/sphinx/var/log/searchd_mysql.pid
# 系统日志存放的位置
log = E:/sphinx/var/log/searchd_mysql.log
# 查询日志存放的位置
query_log = E:/sphinx/var/log/query_mysql.log
}
配置好sphinx.conf,必须建立对应的数据库,当建立索引的时候去要去数据库读取数据并创建索引文件
总结:
1、source 唯一索引名称{} 定义数据源,可以定义多个,每一个数据源对应一个index
a)修改数据库信息
b)修改待带创建索引SQL
2、index 唯一索引名称{} 定义索引,每个索引对应一个数据源
a) 索引文件的名字
b) 索引文件存放的位置
3、indexer{} 只能有一个 (作用:建索引时使用的内存量)
4、searchd{} 只能有一个,sphinx服务器进程
a) 系统日志存放的位置
b) 查询日志存放的位置
3)创建索引
语法:indexer -c 配置文件 索引名称 (注:全部索引–all)
4)在DOS界面对索引进行测试
语法:search -c 配置文件 内容
因为是在DOS窗口测试所以切记更改编码为gbk
三、使用PHP API操作 Sphinx
1、创建Sphinx服务
创建服务:searchd -c 配置文件 –install
删除服务:SC DELETE 服务名
启动服务:net start 服务名
关闭服务:net stop 服务名
2、初体验(PHP操作Sphinx)
<?php
header(‘content-type:text/html;charset=utf-8’);
/**
* 复制sphinx的接口文件到使用目录中
* 步骤1:引入接口文件
* 步骤2:创建服务对象 (new SphinxClient)
* 步骤3:创建服务,语法:setServer(服务器ip地址,端口)
* 步骤4:设置查询条数,语法:setLimits(起始位置,每页显示条数)
* 步骤5:查询,语法:query(关键词,索引名)
*/
//1.引入接口文件
require ‘./sphinxapi.php’;
//2.创建sphinx对象
$sp = new SphinxClient;
//3.设置服务
$sp->setServer(‘localhost’, 9312);
//4.设置分页
$sp->setLimits(0, 10);
//5.去索引中查询
$data = $sp->query(‘冬天’, ‘music’);
echo ‘<pre>’;
print_r($data);die;
源码原因:配置是gbk
解决:修改配置文件为utf8
步骤:
- 修改编码
2.关闭服务
3.创建索引
4.开启服务
3、匹配模式
1)语法
- 语法:$对象->setMatchMode(参数)
- 参数
- SPH_MATCH_ALL 匹配所有词(默认)
- SPH_MATCH_ANY 匹配一个词
- SPH_MATCH_PHRASE 匹配整一个词
- SPH_MATCH_BOOLEAN 将查询看作一个布尔表达式
- SPH_MATCH_EXTENDED 查询看做一个sphinx的表达式
2)模式举例说明
举例:我喜欢PHP
分词:我 喜欢 PHP
测试数据
国外资深记者:我喜欢Vista的11大理由_国外最牛的PHP开源建站平台
为什么现在业界那么多人喜欢黑 PHP 且乐此不疲? – 知乎用户的我回答…
我叫XXXX
世界上最好的语言是PHP吗
PHP是世界上最好的语言
我喜欢PHP,你知道吗
匹配所有词(SPH_MATCH_ALL)
- 说明:【我】、【喜欢】、【PHP】必须都存在,顺序不限
- 结果:
国外资深记者:我喜欢Vista的11大理由_国外最牛的PHP开源建站平台
为什么现在业界那么多人喜欢黑 PHP 且乐此不疲? – 知乎用户的我回答…
我叫XXXX
世界上最好的语言是PHP吗
PHP是世界上最好的语言
我喜欢PHP,你知道吗
匹配一个词(SPH_MATCH_ANY)
- 说明:【我】、【喜欢】、【PHP】只要存在一个就可以
- 结果:
国外资深记者:我喜欢Vista的11大理由_国外最牛的PHP开源建站平台
为什么现在业界那么多人喜欢黑 PHP 且乐此不疲? – 知乎用户的我回答…
我叫XXXX
世界上最好的语言是PHP吗
PHP是世界上最好的语言
我喜欢PHP,你知道吗
脚下留心
匹配整个词(SPH_MATCH_PHRASE)
- 说明:【我】、【喜欢】、【PHP】必须都存在,存储不能变
- 结果:
国外资深记者:我喜欢Vista的11大理由_国外最牛的PHP开源建站平台
为什么现在业界那么多人喜欢黑 PHP 且乐此不疲? – 知乎用户的我回答…
我叫XXXX
世界上最好的语言是PHP吗
PHP是世界上最好的语言
我喜欢PHP,你知道吗
将查询看作一个布尔表达式(SPH_MATCH_BOOLEAN)
- 说明:就是通过运算查询
- 举例:
$rs = $sc->query(‘冬天 !寒冷’, ‘music’);
内容中有冬天,但是没有寒冷的
$rs = $sc->query(‘冬天 | 冷’, ‘music’);
内容中有冬天或者冷
$rs = $sc->query(‘冬天 & 冷’, ‘music’);
内容中有冬天并且有冷
- 结果:(PHP | JAVA PHP & 喜欢)
查询看做一个sphinx的表达式(SPH_MATCH_EXTENDED)
- 说明:可以限制字段里面的查询内容
- 举例:@title 内容 @author 内容 @content 内容
小总结
[概念]
—————–
[安装并通过PHP操作]
步骤1:将sphix解压到指定目录中(因为绿色版所以就安装好了)
步骤2:创建配置文件,然后通过【indexer -c 配置文件 索引名】指定建立索引文件
步骤3:创建sphinx的服务,通过该服务PHP可以操作【searchd -c 配置文件 –install】并且启动服务【net start searchd】
步骤4:复制【sphinxapi.php】然后通过PHP引入操作sphinx
——————————–
[PHP操作步骤]
1、引入sphinxapi.php
2、通过$sc = new SphinxClient创建对象
3、设置服务$sc->setServer(服务器地址,9312)
4、设置条数$sc->setLimits(起始位置,查询条数)
5、查询 $sc->query(关键词,索引);
四、将sphinx的结果转化为具体的信息
1、思路分析
步骤1:通过sphinx的indexer创建索引
步骤2:通过php操作sphinx获取数据id
步骤3:通过php根据数据id去MySQL中查询数据信息
查询
<?php
header(‘content-type:text/html;charset=utf-8’);
/**
* 复制sphinx的接口文件到使用目录中
* 步骤1:引入接口文件
* 步骤2:创建服务对象 (new SphinxClient)
* 步骤3:创建服务,语法:setServer(服务器ip地址,端口)
* 步骤4:设置查询条数,语法:setLimits(起始位置,每页显示条数)
* 步骤5:查询,语法:query(关键词,索引名)
*/
//1.引入接口文件
require ‘./sphinxapi.php’;
//2.创建sphinx对象
$sp = new SphinxClient;
//3.设置服务
$sp->setServer(‘localhost’, 9312);
//4.设置分页
$sp->setLimits(0, 10);
//5.匹配模式
// $sp->SetMatchMode(SPH_MATCH_BOOLEAN);
//6.去索引中查询
$data = $sp->query(‘冬天’, ‘music’);
//7.获取数据ID
$ids = implode(‘,’, array_keys($data[‘matches’]));
//8.去数据库查询数据
$pdo = new PDO(‘mysql:dbname=test’, ‘root’, ‘root’);
$pdostatment = $pdo->query(“select * from music where id in (“.$ids.”)”);
$data = $pdostatment->fetchAll(PDO::FETCH_ASSOC);
// echo ‘<pre>’;
// print_r($data);
foreach ($data as $v) {
echo $v[‘id’] . $v[‘title’] . $v[‘author’] . ‘<br />’;
}
︴多学一招:高亮显示搜索的关键词
<?php
header(‘content-type:text/html;charset=utf-8’);
/**
* 复制sphinx的接口文件到使用目录中
* 步骤1:引入接口文件
* 步骤2:创建服务对象 (new SphinxClient)
* 步骤3:创建服务,语法:setServer(服务器ip地址,端口)
* 步骤4:设置查询条数,语法:setLimits(起始位置,每页显示条数)
* 步骤5:查询,语法:query(关键词,索引名)
*/
//1.引入接口文件
require ‘./sphinxapi.php’;
//2.创建sphinx对象
$sp = new SphinxClient;
//3.设置服务
$sp->setServer(‘localhost’, 9312);
//4.设置分页
$sp->setLimits(0, 10);
//5.匹配模式
// $sp->SetMatchMode(SPH_MATCH_BOOLEAN);
//6.去索引中查询
$data = $sp->query(‘冬天’, ‘music’);
//7.获取数据ID
$ids = implode(‘,’, array_keys($data[‘matches’]));
//8.去数据库查询数据
$pdo = new PDO(‘mysql:dbname=test’, ‘root’, ‘root’);
$pdostatment = $pdo->query(“select * from music where id in (“.$ids.”)”);
$data = $pdostatment->fetchAll(PDO::FETCH_ASSOC);
// echo ‘<pre>’;
// print_r($data);
foreach ($data as $v) {
//自定义方法
$title = str_replace(‘冬天’, ‘<font color=red>冬天</font>’, $v[‘title’]);
$author = str_replace(‘冬天’, ‘<font color=red>冬天</font>’, $v[‘author’]);
$content = str_replace(‘冬天’, ‘<font color=red>冬天</font>’, $v[‘content’]);
echo $v[‘id’] .’___’. $title .’___’. $author . ‘<hr />’;
echo $content . ‘<hr />’;
//【官方语法】
// $row = $sc->buildExcerpts(要添加提示效果的一维数组,索引名,关键词,array(
// ‘before_match’ => ‘<font color=”red”>’,
// ‘after_match’ => ‘</font>’
// ));
//将$v里面的冬天前面追加before_match,后面追加after_match,最后返回索引数组
// $row = $sp->buildExcerpts($v, ‘music’ , ‘冬天’,array(
// ‘before_match’ => ‘<font color=”red”>’,
// ‘after_match’ => ‘</font>’
// ));
// echo $row[0] .’___’. $row[1] .’___’. $row[2] . ‘<hr />’;
// echo $row[3] . ‘<hr />’;
}
增量索引(Sphinx索引更新)
1、什么是增量索引
答:就是更新sphinx索引文件
为什么要学习增量索引
答:因为数据库每天数据都在变化,所以需要在原索引的基础上继续增加索引
使用indexer.exe生成增量索引 (语法) –merge 主索引名 新索引名 –rotate
创建索引语法:indexer -c 配置文件 索引名
合并索引语法:indexer -c 配置文件 –merge 主索引名 新索引名 –rotate
具体操作
1)创建数据库(用于记录哪些数据已经被创建索引)
# 数据库SQL语句
create table sphinx
(
max_id int unsigned not null default 0
)
2)主索引的数据源初始化数据,加标记当前已更新记录最大ID
# sql_query属性:取出要创建索引的数据
sql_query = SELECT id, title, content FROM music
# 建完索引这后 ,把最后一条记录的id存到sphinx表中
# 在主查询(sql_query)之后执行的SQL
sql_query_post = INSERT INTO sphinx SELECT MAX(id) FROM music
3)修改配置文件(增加新索引)
- 步骤1:将etc/csft_mysql.conf复制并更名为sphinx.conf (注:已经有了就无需操作)
- 步骤2:打开shpinx.conf修改内容如下
# 数据源
source music_add
{
# 下面是sql数据库特有的端口,用户名,密码,数据库名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass = root
sql_db = music
sql_port = 3306
sql_query_pre = SET NAMES utf8
# (SELECT MAX(max_id) FROM sphinx) 目的,规避以及建立的索引数据
sql_query = SELECT id, title, author,content FROM music WHERE id > (SELECT MAX(max_id) FROM sphinx)
# 建完索引这后 ,把最后一条记录的id存到sphinx表中
# 在主查询(sql_query)之后执行的SQL
sql_query_post = UPDATE sphinx SET max_id = (SELECT MAX(id) FROM music)
}
# 数据索引
index music_add
{
# 对应的source数据来源名称
source = music_add
path = E:/sphinx/var/data/music_add
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
# 词库文件所在的目录
charset_dictpath = E:/sphinx/etc/
charset_type = zh_cn.utf-8
}
4)增量的索引文件合并到主索引文件上去,并标记当前已更新记录最大ID
步骤1:停止服务 -> music创建主索引 -> 开启服务
步骤2:给新数据创建索引(注:不需要开启服务)
步骤3:将新数据和老数据合并(注:不需要开启服务)
5)新增测试数据(注:新增数据后需要重复如下步骤【创建新索引、合并老索引】)
6)测试
总结,实现增量索引的步骤
- 步骤1:创建数据库,用来记录已经创建索引的数据
# 数据库SQL语句
create table sphinx
(
max_id int unsigned not null default 0
)
- 步骤2:修改etc\sphinx.conf文件
步骤2.1 修改music索引的数据源,增加下属代码,用户当music第一次执行后记录已经创建索引数据的最大id
# 建完索引这后 ,把最后一条记录的id存到sphinx表中
# 在主查询(sql_query)之后执行的SQL
sql_query_post = INSERT INTO sphinx SELECT MAX(id) FROM music
步骤2.2 新增music_add索引和数据源
# 数据源
source music_add
{
# 下面是sql数据库特有的端口,用户名,密码,数据库名等。
type = mysql
sql_host = localhost
sql_user = root
sql_pass = root
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
# (SELECT MAX(max_id) FROM sphinx) 目的,规避以及建立的索引数据
sql_query = SELECT id, title, author,content FROM music WHERE id > (SELECT MAX(max_id) FROM sphinx)
# 建完索引这后 ,把最后一条记录的id存到sphinx表中
# 在主查询(sql_query)之后执行的SQL
sql_query_post = UPDATE sphinx SET max_id = (SELECT MAX(id) FROM music)
}
# 数据索引
index music_add
{
# 对应的source数据来源名称
source = music_add
path = E:/sphinx/var/data/music_add
docinfo = extern
mlock = 0
morphology = none
min_word_len = 1
html_strip = 0
# 词库文件所在的目录
charset_dictpath = E:/sphinx/etc/
charset_type = zh_cn.utf-8
}
- 步骤3:
步骤3.1 停止服务- > 先执行主索引【music】 -> 开启服务
步骤3.2 再执行新增索引【music_add】 (注:无需关闭服务)
步骤3.3 将【music_add】索引和【music】索引合并 (注:无需关闭服务)
- 步骤4:测试
后期统一搞点新数据重复下属步骤
步骤3.2 再执行新增索引【music_add】
步骤3.3 将【music_add】索引和【music】索引合并
︴扩展:Windows与Linux系统中的定时任务
步骤1:新建xxx.bat文件将创建新增索引的DOS命令放进去
net stop searchd
e:\sp\bin\indexer -c e:\sp\etc\sphinx.conf music_add
e:\sp\bin\indexer -c e:\sp\etc\sphinx.conf –merge music music_add –rotate
net start searchd
步骤2:把这个xxx.bat文件添加到windows系统上的“计划任务”让系统定时执行这个文件中的两个任务。