【PHP征文】php 使用 sphinx 实现实时 innodb 全文索引

原文地址:http://cloudbbs.org/forum.php?mod=viewthread&tid=7992


目录:
须知 --------------------------------- 1楼
一.安装 ------------------------------ 1楼
二.配置 ------------------------------ 1楼
三.启动sphinxsearch -------------- 2楼
四.测试 ------------------------------ 2楼
五.下载sphinxapi.php ------------- 2楼
六.PHP使用Sphinx ----------------- 3楼
七.sphinx定时更新索引 ----------- 3楼
八.结束语 --------------------------- 3楼


环境:ubuntu 12.04 , mysql5.5 , php5.3 , nginx1.1
事前须知:
1.
sphinx可以实现全文索引,但不会随着数据的增加而自动增加索引,
所以需要重新生成索引,但每次都全部建立开销比较大,所以使用增量索引实现实时检索。之后通过定时任务来更新主索引。
方案如下:
每分钟更新增量索引一次,每天更新主索引一次。

2.
sphinx配置文件中,数据源和索引的配置可以继承(详见下面的配置)

一. 安装
sudo apt-get install sphinxsearch
复制代码


二.配置
1.前置工作

在配置以前需要在数据库里添加一个表用于增量备份。
该表有2个字段,1个字段关联一个索引,另一个字段记录被索引字段的最后一个id。
而增量索引根据第二个字段去索引数据。

CREATE TABLE IF NOT EXISTS `search_counter` (
`counterid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`max_doc_id` int(11) unsigned NOT NULL,
PRIMARY KEY (`counterid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
复制代码


2.配置sphinx

在/etc/sphinxsearch/下
有一个示例配置文件 sphinx.conf.sample,有哪些参数不理解可以看看这个文档
在这个文件夹下,我们新建一个文件sphinx.conf
内容如下:
#凡是后边带有(手册),(网上)的,都是我不确定或者我不懂的。
#设置数据源
source info_src
{
#绑定数据库
type = mysql
sql_host = localhost
sql_user = mysql_name
sql_pass = mysql_pwd
sql_db = mysql_db
sql_port = 3306 # optional, default is 3306

#个人理解:sql_query_pre 是生成索引前置语句
sql_query_pre = set names utf8
#记录生成索引时的最高id
sql_query_pre = replace into search_counter select 1,max(id) from infos

#生成索引的主查询语句,第一列必须是唯一标识符,后两列是要生成索引的列。
sql_query = SELECT id, title, content FROM infos
}

#配置索引
index info_ind
{
#数据源
source = info_src
#索引存放位置
path = /var/lib/sphinxsearch/data/info
#文档属性值的存储方法。分别为extern,inline和none(手册)
docinfo = extern
#是否为缓存的数据使用内存锁(手册)
mlock = 0
#内置预处理类型,比如stem_en,stem_ru,soundex,libstemmer_german等。默认为none。(手册)
morphology = none
#索引单词的最小长度。
min_word_len = 1
charset_type = utf-8

#指定中文编码表,不设置将不能搜索中文(网上资料)
charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
#在索引时,是否将html抽去掉,默认为0,不抽取
html_strip = 1
#索引的n-gram长度(手册)
ngram_len = 1
#CJK索引的n-gram字符列表,默认为空(手册)
ngram_chars = U+3000..U+2FA1F
}

#设置数据源,继承自info_src,该数据源用于增量索引
source infoadd_src:info_src
{
#覆盖父数据源的主查询语句,其他一样的就不用写了。
sql_query = SELECT N_Id, N_Title,SummerText FROM hlb_infos where n_id >(select max_doc_id from search_counter where counterid=1)
}

#设置索引,继承自info_ind,该索引用于增量索引
index infoadd_ind:info_ind
{
#覆盖
source = infoadd_src
path = /var/lib/sphinxsearch/data/infoadd
}

#indexer是sphinx自带的程序,负责连接数据源,生成索引。
#indexer的相关配置
indexer
{
#indexer使用的索引缓冲区的内存限制,可以用K和M来指定单位,不能用G。最大2047M。(手册)
mem_limit = 128M
#写缓冲区的最大大小,默认1M。这些缓冲区是除了mem_limit设置以外的分配的缓存(手册)
# write_buffer = 1M
}

#searchd是shipinx的守护程序,负责搜素索引。
#searchd的相关配置
searchd
{
#searchd守护程序运行的主机,端口或者主机:端口,或者unix的socket路径(手册)
#默认配置有2个,我也不知道为什么。
listen = 9312
listen = 9306:mysql41
log = /var/log/sphinxsearch/searchd.log
query_log = /var/log/sphinxsearch/query.log
#客户读的超时时间
read_timeout = 5
#请求超时
client_timeout = 300
#可以拓展的最多的子集个数
max_children = 30
pid_file = /var/run/sphinxsearch/searchd.pid
#查询后,最多匹配数
max_matches = 1000
#获得索引后,是否预先打开索引(手册)
seamless_rotate = 1
#是否预先打开所有索引,或者在每次查询时打开(手册)
preopen_indexes = 1
#在索引旋转时是否解开旧的索引(手册)
unlink_old = 1
#如果设置该项,那么属性更新共享池大小。这样将会禁止属性刷新(手册)
mva_updates_pool = 1M
#客户查询数据包和代理响应的最大包大小。默认为8M(手册)
max_packet_size = 8M
#过滤器的最大数目。默认为256(手册)
max_filters = 256
#每个过滤器的最大数目。默认为4096(手册)
max_filter_values = 4096
# max allowed per-batch query count (aka multi-query count) (手册)
max_batch_queries = 32
# 多处理模式。默认为fork。值有 none, fork, prefork, threads。
workers = threads # for RT to work

}
复制代码

3.开启sphinxsearch功能
编辑/etc/default/sphinxsearch 将START=no 修改为 START=yes
三.启动sphinxsearch


1.创建索引
sudo indexer --rotate info_ind
sudo indexer --rotate infoadd_ind
复制代码

indexer 参数介绍
--quiet 安静模式
--rotate 建立索引后重启searchd


2.启动

sudo /etc/init.d/sphinxsearch start
复制代码


启动成功后会有如下提示:
Starting sphinxsearch: Sphinx 2.0.4-release (r3135)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc ([url=http://sphinxsearch.com]http://sphinxsearch.com[/url])

using config file '/etc/sphinxsearch/sphinx.conf'...
WARNING: compat_sphinxql_magics=1 is deprecated; please update your application and config
listening on all interfaces, port=9312
listening on all interfaces, port=9306
precaching index 'info_ind'
precaching index 'infoadd_ind'
precached 2 indexes in 0.002 sec
sphinxsearch.
复制代码


四.测试
search -i info_ind -e '3' -l 3
复制代码


-i 使用哪个索引
-e 使用extended模式
-l 3 只显示前3个结果
'3' 搜索词
root@ubuntu:/$ search -i info_ind -e '3' -l 3

Sphinx 2.0.4-release (r3135)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc ([url=http://sphinxsearch.com]http://sphinxsearch.com[/url])

using config file '/etc/sphinxsearch/sphinx.conf'...
index 'info_ind': query '3 ': returned 134 matches of 134 total in 0.016 sec

displaying matches:
1. document=35948, weight=1687
2. document=17678, weight=1664
3. document=17767, weight=1664

words:
1. '3': 134 documents, 148 hits
复制代码

一共有134个匹配(matches).
好了,到这里sphinx已经配置完了。


五.下载sphinxapi.php
1.获取版本号
root@ubuntu:/$ searchd -h
Sphinx 2.0.4-release (r3135)
Copyright (c) 2001-2012, Andrew Aksyonoff
Copyright (c) 2008-2012, Sphinx Technologies Inc ([url=http://sphinxsearch.com]http://sphinxsearch.com[/url])

Usage: searchd [OPTIONS]

Options are:

...以下省略
复制代码

得知版本号是sphinx2.0.4

2.去官网下载Sphinx 2.0.4-release
http://sphinxsearch.com/downloads/archive/
找到tar.gz的sphinx 2.0.4 release ,下载。
解压后去api文件夹里找到sphinxapi.php。

六.PHP使用Sphinx
直接上程序啦.
PHP代码
<?php
require('include/sphinxapi.php');
$sphinx = new SphinxClient();
$host = 'localhost';
$port = 9312;
$sphinx->SetServer($host,$port);
//设置模式为extended
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
//只取3个结果
$sphinx->SetLimits(0, 3);
//使用的索引
$index = 'info_ind,infoadd_ind';
//在title,content上搜索 ‘吗’
$word = '吗';
//在title,content上搜索‘吃’或者‘今天’
//$word = '吃|今天';
//在title上搜索‘吃’或者‘今天’
//$word = '@title 吃|今天';

$result = $sphinx->Query($word,$index);
print_r($result);
?>
在result中,有个键名为matches,若搜索结果不为0,则包含id集合,如果搜索结果为0,则不存在matches。

完整示例如下(示例中的mysql类是自己封装的):

PHP代码
<?php
require('config/configure.inc.php');
require('include/sphinxapi.php');
require('include/mysql.class.php');
$sphinx = new SphinxClient();
$host = 'localhost';
$port = 9312;
$sphinx->SetServer($host,$port);
$sphinx->SetMatchMode(SPH_MATCH_EXTENDED);
// $sphinx->SetArrayResult(TRUE);
$sphinx->SetLimits(0, 3);
$index = 'info_ind,infoadd_ind';
$word = '@title 工商年检|转让五千万';
$result = $sphinx->Query($word,$index);
// print_r($result);
if(key_exists('matches',$result)){
$db = new Mysql();
$db->connect();
$sql = 'select id,title,content from infos where id in ('.implode(',', array_keys($result['matches'])).')';
// echo $sql;
$infos = $db->search($sql,'n_id');
print_r($infos);
}
?>
七.sphinx定时更新索引
sphinx已经设置了每天自动整合。编辑/etc/cron.d/sphinxsearch
在第一句话开头添上#号,注释掉这一句,并添加定时任务。
# Rebuild all indexes daily and notify searchd.
#默认每天更新索引
#@daily root . /etc/default/sphinxsearch && if [ "$START" = "yes" ] && [ -x /usr/bin/indexer ]; then /usr/bin/indexer --quiet --rotate --all; fi
#每分钟重新建立增量索引
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59 * * * * root . /etc/default/sphinxsearch && if [ "$START" = "yes" ] && [ -x /usr/bin/indexer ]; then /usr/bin/indexer --quiet --rotate infoadd_ind; fi

#每天3点40重新建立主索引,并建立增量索引
40 03 * * * root . /etc/default/sphinxsearch && if [ "$START" = "yes" ] && [ -x /usr/bin/indexer ]; then /usr/bin/indexer --quiet --rotate info_ind && /usr/bin/indexer --quiet --rotate infoadd_ind; fi
复制代码


八.结束语

在实际生产环境中,中文搜索是需要分词的,在这里就不多做介绍了。我用的分词工具是scws。
这篇文章也算是凑巧,刚刚完成sphinx的配置,一边配置,一边测试,一边写的,恰巧碰上sae征文。
就过来献丑了。


顺便 已申请普通开发者认证,求推荐啊~应用地址
http://qianqianqian.sinaapp.com

其中钓鱼和音乐盒也都是半成品,单是还是想来试试运气。
求推荐~~~

推荐链接
http://sae.sina.com.cn/?m=home&a=devlevel&level=normal_level&voteme=fbejCB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值