(自己编写+网上搜集资料)
一、Windows下安装:
1、http://sphinxsearch.com/downloads/下载sphinx-2.0.1-beta-win32
2、解压,到硬盘,比如D:\sphinx-2.0.1-beta-win32
3、安装完成
Eg:
CREATETABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`school` varchar(20) NOT NULL,
`sex` varchar(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=31 ;
二、配置
1、 将D:\sphinx-2.0.1-beta-win32\sphinx.conf.in文件copy一下,重命名为sphinx.conf,修改配置,也可使用sphinx-min.conf.in的内容
2、 sphinx.conf的内容如下,
(1)sphinx.conf的内容组成
source 源名称1{
…
}
index 索引名称1{
source=源名称1
…
}
source 源名称2{
…
}
index 索引名称2{
source = 源名称2
…
}
从组成我们可以发现sphinx可以定义多个索引与数据源,不同的索引与数据源可以应用到不同表或不同应用的全文检索。
(2)实例
#
# Minimal Sphinx configuration sample(clean, simple, functional)
#
source userhx
{
type = mysql
sql_host = localhost
sql_user = root
sql_pass =
sql_db = usertest
sql_port = 3306 # optional, default is 3306
sql_query = \
SELECTid, name, school, sex \
FROMuser
#sql_attr_uint = group_id
#sql_attr_timestamp = date_added
sql_query_info = SELECT * FROM eht_articles WHERE id=$id
}
index userindex
{
source = userhx
path = D:/sphinx-index/userindex/
docinfo = extern
charset_type = sbcs
}
indexer
{
mem_limit = 32M
}
searchd
{
listen = 9312
listen = 9306:mysql41
log =D:/workspacePhp/user/log/searchd.log
query_log = D:/workspacePhp/user/log/query.log
read_timeout = 5
max_children = 30
pid_file =D:/workspacePhp/user/log/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 1
unlink_old = 1
workers = threads # for RT to work
}
注意:index userindex中的path必须以”/”结束,如果D:/sphinx-index/userindex,那生成的索引将会是以userindex为文件名userindex.spa、userindex.spi等
三、配置说明:
#type 数据库类型,目前支持mysql与pgsql
#strip_html 是否去掉html标签
#sql_host 数据库主机地址
#sql_user 数据库用户名
#sql_pass 数据库密码
#sql_db 数据库名称
#sql_port 数据库采用的端口
#sql_query_pre 执行sql前要设置的字符集,用utf8必须SETNAMES utf8
#sql_query 全文检索要显示的内容,在这里尽可能不使用where或group by,将where与groupby的内容交给sphinx,由sphinx进行条件过滤与groupby效率会更高
#注意:select 出来的字段必须至少包括一个唯一主键(ARTICLESID)以及要全文检索的字段,你计划原本在where中要用到的字段也要select出来
#这里不用使用orderby
#sql_attr_开头的表示一些属性字段,你原计划要用在where,orderby,groupby中的字段要在这里定义
#根据我们原先的SQL:
#select * from user where name like ? and school=? orderby sex desc
#我们需要对name, school, sex进行属性定义(这四个字段也要在select的字段列表中),定义时不同的字段类型有不同的属性名称,具体可以见sphinx.conf.in中的说明
index部分配置项说明
#source 数据源名
#path 索引记录存放目录,如d:/sphinx/data/cgfinal,实际存放时会存放在d:/sphinx/data目录,然后创建多个cgfinal名称,不同扩展名的索引文件。
#其他的配置如min_word_len,charset_type,charset_table,ngrams_chars,ngram_len这些则是支持中文检索需要设置的内容。
#如果检索的不是中文,则charset_table,ngrams_chars,min_word_len就要设置不同的内容,具体官方网站的论坛中有很多,大家可以去搜索看看。
四、生成索引
cmd进入sphinx的根目录 D:\sphinx-2.0.1-beta-win32
命令:D:\sphinx-2.0.1-beta-win32>bin\indexer --config sphinx.confuserindex
如果在sphinx.conf中配置了多个数据源,想一次性全部索引则
D:\sphinx-2.0.1-beta-win32>bin\indexer--config sphinx.conf –all
五、启动sphinx
D:\sphinx-2.0.1-beta-win32\bin>searchd.exe--config D:\sphinx-2.0.1-beta-win32\sphinx.conf
六、搜索
通过Sphinx自带的search(在bin目录)就可以在命令行进行搜索:
(搜索qq)
windows 上:
D:\sphinx-2.0.1-beta-win32\bin>search -cd:/sphinx-2.0.1-beta-win32/sphinx.conf qq
Linux上:
cd /usr/local/sphinx
./bin/search -c sphinx.conf qq
两种搜索方式:
一是通过Sphinx官方提供的API接口(接口有Python,Java,Php三种版本)
以java为例
(sphinxapi.php在下载的包中api文件夹下存在)
在sphinxapi.php 中修改SphinxClient(),代码
$this->_host = "localhost";
$this->_port = 9312;
(与sphinx.conf保持一致)
调用时的代码:
require ( "sphinxapi.php");
$cl = new SphinxClient();
$cl ->SetServer('localhost',9312);(不修改sphinxapi.php代码,添加此代码就可)
$q='123';
$index='userindex';
$res = $cl->Query ( $q, $index );
print_r($res);
二、
(1)(sphinx安装没有找到windows下的安装步骤,此为linux安装步骤,未实验)
下载sphinx-2.0.1-beta.tar.gz (http://sphinxsearch.com/downloads)
是通过安装SphinxSE,然后创建一个中介sphinxSE类型的表,再通过执行特定的SQL语句实现。
采用sphinxSE必须要求为mySQL安装sphinxSEEngine驱动
SphinxSE Engine安装
解压:
tar -xzvf sphinx-2.0.1-beta.tar.gz
创建sphinx文件夹:
mkdir mysql-5.1.48/storage/sphinx
将sphinx目录下mysqlse下所有文件拷贝到mysql目录的storage/sphinx下
cp -r sphinx-2.0.1-beta/mysqlse/ mysql-5.1.48/storage/sphinx
进到mysql源码包的解压目录
cd mysql-5.1.48
sh BUILD/autorun.sh
./configure
make
注意:这里到make这步即可,不用install
将make好的文件复制到当前运行的mysql目录中
cp storage/sphinx/.libs/ha_sphinx.*/usr/local/mysql/lib/plugin
更改所有者:
chown mysql.mysql /usr/local/mysql/lib/plugin/*
登陆mysql加载sphinx引擎模块:
/usr/local/mysql/bin/mysql -u root -p -h localhost
加载sphinx存储模块:
mysql> INSTALL PLUGIN sphinx SONAME'ha_sphinx.so';
检查引擎模块是否正常加载:
mysql> show engines;
安装完成!如果要卸载存储模块使用:
mysql> UNINSTALL PLUGIN sphinx;
(2)
要创建一张sphinx 专用表,你可以这样建
CREATE TABLE `sphinx` (
`id` int(11) NOT NULL,
`weight` int(11) NOT NULL,
`query` varchar(255) NOT NULL,
`CATALOGID` INT NOT NULL,
`EDITUSERID` INT NOT NULL,
`HITS` INT NULL,
`ADDTIME` INT NOT NULL,
KEY `Query` (`Query`)
) ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNE
注:与一般mysql表不同的是ENGINE=SPHINX DEFAULT CHARSET=utf8CONNECTION='sphinx://localhost: 9312/userindex';,这里表示这个表采用SPHINXSE引擎,字符集是 utf8,与sphinx的连接串是'sphinx://localhost:3312/userindex,userindex是索引名称
根据sphinx官方说明,这个表必须至少有三个字段,字段起什么名称无所谓,但类型的顺序必须是integer,integer,varchar,分别表示记录标识document ID,匹配权重weight与查询query,同时document ID与query必须建索引。另外这个表还可以建立几个字段,这几个字段的只能是integer或TIMESTAMP类型,字段是与sphinx的结果集 绑定的,因此字段的名称必须与在sphinx.conf中定义的属性名称一致,否则取出来的将是Null值。
比如我在上面有定义了sql_attr_uint=CATALOGID,sql_attr_uint= EDITUSERID,sql_attr_uint = HITS,sql_attr_timestamp =ADDTIME,那么在这个表里头,你就可以再定义CATALOGID,EDITUSERID,HITS,ADDTIME四个字段。
(3
通过sql语句实现查询。通过select * from sphinx where query='sphinx表达式'的方式可以实现查询,通过让sphinx表与eht_articles或其他表并联查询(条件是 sphinx.id=eht_articles.Articlesid)还可以实现更为复杂的sql,基本上可以符合我们日常的要求。
sphinx表达式在sphinx的手册中也提到了,这里我简单说明几条:
· query='关键字' ,关键字就是你要搜索的关键字,如query='CGArt'表示你要全文搜索CGArt
· mode,搜索模式,值有:all,any,phrase,boolean,extended,默认是all
· sort,排序模式,必须是relevance,attr_desc,attr_asc,time_segments,extended中的一种,在所有模式中除了relevance外,属性名(或用extended排序)前面都需要一个冒号。
... wherequery='test;sort=attr_asc:hits';
... wherequery='test;sort=extended:@weight desc,hits asc';
· offset,结果记录集的起始位置,默认是0
· limit,从结果记录集中取出的数量,默认是20条
· index,要搜索的索引名称
... wherequery='test;index=cgfinal';
... wherequery='test;index=test1,test2,test3;';
· minid,maxid,匹配最小与最大文档ID
· weights,以逗号分割的分配给sphinx全文检索字段的权重列表
... wherequery='test;weights=1,2,3;';
· filter,!filter,以逗号分隔的属性名与一堆要匹配的值
#只包括1,5,19的组
... wherequery='test;filter=group_id,1,5,19;';
#不包括3,11的组
... wherequery='test;!filter=group_id,3,11';
· range,!range,逗号分隔的属性名一最小与最大要匹配的值
#从3至7的组
... wherequery='test;range=group_id,3,7;';
#不包括从5至25的组
... wherequery='test;!range=group_id,5,25;';
· maxmatches,每个查询最大匹配的值
... wherequery='test;maxmatches=2000;';
· groupby,group by 方法与属性
... wherequery='test;groupby=day:published_ts;';
... wherequery='test;groupby=attr:group_id;';
· groupsort,group by 的排序
... wherequery='test;gropusort='@count desc';
需要注意的重要一点是让sphinx进行排序,过滤,切分结果记录集比用 MySQL的where,orderby 和limit将有更好的效率。有两个原因,首先sphinx做了很多优化,在这些任务上它比mySQL做得更出色,其次searchd在打 包,sphinxSE在传输与解包上需要的数据量更少。
你可以通过运用join在sphinxSE的搜索表和其他引擎类型的表做并联查询。这有一个从example.sql中documents表的例子:
mysql> SELECT content, date_added FROM test.documents docs
-> JOIN t1 ON (docs.id=t1.id)
-> WHERE query="one document;mode=any";
+-------------------------------------+---------------------+
| content | docdate |
+-------------------------------------+---------------------+
| this is my test document number two | 2006-06-17 14:04:28 |
| this is my test document number one | 2006-06-17 14:04:28 |
+-------------------------------------+---------------------+
2 rows in set (0.00 sec)
mysql> SHOW ENGINE SPHINX STATUS;
+--------+-------+---------------------------------------------+
| Type | Name | Status |
+--------+-------+---------------------------------------------+
| SPHINX | stats | total: 2, total found: 2, time: 0, words: 2 |
| SPHINX | words | one:1:2 document:2:2 |
+--------+-------+---------------------------------------------+
2 rows in set (0.00 sec)
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画;mode=extended;sort=extended:hitsdesc,catalogid desc'
8. SphinxSE的SQL查询例子演练
· 从eht_articles中查询标题含有“动画”关键字的记录。
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画;mode=extended'
提示
说明:要指定某个字段进行搜索,要用@字段名+空格+关键字+分 号+mode=extended如果不指定字段,则系统会对TITLE,CONTENTS进行搜索 ,对什么字段进行全文检索取决于在sphinx.conf中sql_query定义的select 中的字段(文本类型)
· 从eht_articles中查询文章内容或标题含有“CGArt”关键字的记录。
select c.* from eht_articlesas c,sphinx as t where c.articlesid=sphinx.id and query='动画'
· 若AUTHOR,TITLE,CONTENTS三个字段都全文索引了,但只想搜title,或contents中含有“动画”关键字的文章
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画 |@contents 动画;mode=extended'
· 查询标题含有“动画”关键字,catalogid为7,edituserid为1的记录
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画;filter=edituserid,1;filter=catalogid,7;mode=extended'
提示
采用filter=字段名称,值就相当于where中的 字段名=值,filter提到的字段必须在sphinx的source部分的字段属性定义中定义,如
sql_attr_uint = CATALOGID
sql_attr_uint = EDITUSERID
sql_attr_uint = HITS
sql_attr_timestamp = ADDTIME
· 查询标题含有“动画”关键字,按人气Hits从大至小,栏目ID从大至小排序
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画;mode=extended;sort=extended:hitsdesc,catalogid desc'
在sphinx中,select出来的内容是按weight从大至小排序的,weight是根据sphinx内部一定的算法算出来的,越大就表示越匹配,如果想按匹配度从大至小排序,则可以:
select c.* from eht_articlesas c,sphinx as t where c.articlesid=t.id and query='@title 动画;mode=extended;sort=@weightdesc'
· 搜内容或标题含有优秀或Icon或设计,按catalogid分组,按匹配度从高至低排序
·
select t.*,c.* fromeht_articles as c,sphinx as t where c.articlesid=t.id and query='优秀 |Icon | 设计;mode=extended;groupby=attr:catalogid;groupsort=@weight;'