内容简介:Sphinx是什么:由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。Sphinx创建索引的速度:创建100万条记录的索引只需3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。但是sphinx只支持英文全文检索,对中文不太铭感,于是就引入了swcs分词,其实也可以用Coreseek来建立中文索引,他的内核就是sphinx;
Sphinx是什么:由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。
Sphinx创建索引的速度:创建100万条记录的索引只需3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。
但是sphinx只支持英文全文检索,对中文不太铭感,于是就引入了swcs分词,其实也可以用Coreseek来建立中文索引,他的内核就是sphinx;
下面就简单说下sphinx+swcs的用法:
1.环境:
PHP 5.6+centos 6.5+mysql Ver 14.14 Distrib 5.1.73
2.安装Sphinx:【安装之前检查是否安装有gcc】
cd /usr/local/src wget http://sphinxsearch.com/files/sphinx-2.3.1-beta.tar.gz tar -zxf sphinx-2.3.1-beta.tar.gz cd sphinx-2.3.1-beta ./configure --prefix=/usr/local/sphinx --with-mysql=/usr/local/mysql ./configure --prefix=/usr/local/sphinx --with-mysql-includes=/usr/include/mysql/ --with-mysql-libs=/usr/lib/mysql/ make && make install
3.安装sphinxclient
cd /usr/local/src/sphinx-2.3.1-beta/api/libsphinxclient/ ./configure --prefix=/usr/local/sphinx/libsphinxclient make && make install
4.安装pecl扩展sphinx
wget https://pecl.php.net/get/sphinx-1.3.3.tgz tar -zxf sphinx-1.3.3.tgz cd sphinx-1.3.3 phpize ./configure --with-sphinx=/usr/local/sphinx/libsphinxclient --with-php-config=php-config make && make install echo "[Sphinx]" >> /etc/php.ini echo extension=sphinx.so > /etc/php.ini
5.安装swcs扩展
wget http://www.xunsearch.com/scws/down/scws-1.2.2.tar.bz2 tar -jxf scws-1.2.2.tar.bz2 cd scws-1.2.2 ./configure --prefix=/usr/local/scws/ make && make install cd ./phpext/ phpize ./configure --with-php-config=php-config make && make install echo "[scws]" >> /etc/php.ini echo extension = scws.so > /etc/php.ini echo scws.default.charset = utf-8 >> /etc/php.ini echo scws.default.fpath = /usr/local/scws/etc >> /etc/php.ini
6.安装词库
wget http://www.xunsearch.com/scws/down/scws-dict-chs-utf8.tar.bz2 tar xvjf scws-dict-chs-utf8.tar.bz2 -C /usr/local/scws/etc/ chown www:www /usr/local/scws/etc/dict.utf8.xdb
7.创建测试数据
CREATE TABLE IF NOT EXISTS `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `content` text NOT NULL, `created` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='全文检索测试的数据表' AUTO_INCREMENT=11 ; INSERT INTO `items` (`id`, `title`, `content`, `created`) VALUES (1, 'linux mysql集群安装', 'MySQL Cluster 是 MySQL 适合于分布式计算环境的高实用、可拓展、高性能、高冗余版本', '2016-09-07 00:00:00'), (2, 'mysql主从复制', 'mysql主从备份(复制)的基本原理 mysql支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器', '2016-09-06 00:00:00'), (3, 'hello', 'can you search me?', '2016-09-05 00:00:00'), (4, 'mysql', 'mysql is the best database?', '2016-09-03 00:00:00'), (5, 'mysql索引', '关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车', '2016-09-01 00:00:00'), (6, '集群', '关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车', '0000-00-00 00:00:00'), (9, '复制原理', 'redis也有复制', '0000-00-00 00:00:00'), (10, 'redis集群', '集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规则放入多个不同的服务器节点,来降低单节点服务器的压力', '0000-00-00 00:00:00'); CREATE TABLE IF NOT EXISTS `sph_counter` ( `counter_id` int(11) NOT NULL, `max_doc_id` int(11) NOT NULL, PRIMARY KEY (`counter_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='增量索引标示的计数表';
8.配置sphinx.conf
##数据源items
source items {
##说明数据源的类型。数据源的类型可以是:mysql,pgsql,mssql,xmlpipe,odbc,python
type = mysql
## 下面是 sql 数据库特有的端口,用户名,密码,数据库名等。
sql_host = localhost
sql_user = root
sql_pass = root
sql_db = test
## 如果是使用unix sock连接可以使用这个。
# sql_sock = /tmp/mysql.sock
## indexer和mysql之间的交互,需要考虑到效率和安全性。
## 比如考虑到效率,他们两者之间的交互需要使用压缩协议;考虑到安全,他们两者之间的传输需要使用ssl
## 那么这个参数就代表这个意思,0/32/2048/32768 无/使用压缩协议/握手后切换到ssl/Mysql 4.1版本身份认证。
# mysql_connect_flags = 32
## 当mysql_connect_flags设置为2048(ssl)的时候,下面几个就代表ssl连接所需要使用的几个参数。
# mysql_ssl_cert = /etc/ssl/client-cert.pem
# mysql_ssl_key = /etc/ssl/client-key.pem
# mysql_ssl_ca = /etc/ssl/cacert.pem
## mssql特有,是否使用windows登陆
# mssql_winauth = 1
## mssql特有,是使用unicode还是单字节数据。
# mssql_unicode = 1 # request Unicode data from server
## odbc的dsn串
# odbc_dsn = DBQ=C:\data;DefaultDir=C:\data;Driver={Microsoft Text Driver (*.txt; *.csv)};
## sql某一列的缓冲大小,一般是针对字符串来说的。
## 为什么要有这么一种缓冲呢?
## 有的字符串,虽然长度很长,但是实际上并没有使用那么长的字符,所以在Sphinx并不会收录所有的字符,而是给每个属性一个缓存作为长度限制。
## 默认情况下非字符类型的属性是1KB,字符类型的属性是1MB。
## 而如果想要配置这个buffer的话,就可以在这里进行配置了。
# sql_column_buffers = content=12M, comments=1M
## indexer的sql执行前需要执行的操作。
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type = OFF
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM items
## 有的时候有多个表,我们想要查询的字段在其他表中。这个时候就需要对sql_query进行join操作。
## 而这个join操作可能非常慢,导致建立索引的时候特别慢,那么这个时候,就可以考虑在sphinx端进行join操作了。
## sql_joined_field是增加一个字段,这个字段是从其他表查询中查询出来的。
## 这里封号后面的查询语句是有要求的,如果是query,则返回id和查询字段,如果是payload-query,则返回id,查询字段和权重。
## 并且这里的后一个查询需要按照id进行升序排列。
# sql_joined_field = tags from query; SELECT docid, CONCAT('tag',tagid) FROM tags ORDER BY docid ASC
# sql_joined_field = wtags from payload-query; SELECT docid, tag, tagweight FROM tags ORDER BY docid
## 当数据源数据太大的时候,一个sql语句查询下来往往很有可能锁表等操作。
## 那么我么就可以使用多次查询,那么这个多次查询就需要有个范围和步长,sql_query_range和sql_range_step就是做这个使用的。
## 获取最大和最小的id,然后根据步长来获取数据。比如下面的例子,如果有4500条数据,这个表建立索引的时候就会进行5次sql查询。
## 而5次sql查询每次的间隔时间是使用sql_ranged_rhrottle来进行设置的。单位是毫秒。
sql_query_range = SELECT MIN(id), MAX(id) FROM items \
WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
sql_range_step = 1000
sql_ranged_throttle = 1000
## indexer的sql执行语句
sql_query = SELECT id, title, content, created, 0 as deleted FROM items \
WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1) \
AND id >= $start AND id <= $end
## 时间戳属性,经常被用于做排序
sql_attr_timestamp = created
## bool属性
sql_attr_bool = deleted
}
## sphinx的source是有继承这么一种属性的,意思就是除了父source之外,这个source还有这个特性
source items_delta : items {
sql_query_pre = SET NAMES utf8
sql_query_range = SELECT MIN(id), MAX(id) FROM items \
WHERE id > (SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
sql_query = SELECT id, title, content, created, 0 as deleted FROM items \
WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) \
AND id >= $start AND id <= $end
## 取后查询,在sql_query执行后立即操作。
## 它和sql_query_post_index的区别就是执行时间不同 ## sql_query_post是在sql_query执行后执行,而sql_query_post_index是在索引建立完成后才执行。
## 所以如果要记录最后索引执行时间,那么应该在sql_query_post_index中执行。
sql_query_post_index = set @max_doc_id :=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
sql_query_post_index = REPLACE INTO sph_counter SELECT 2, IF($maxid, $maxid, @max_doc_id)
}
#主索引
index items {
source = items
path = /usr/local/sphinx/var/data/items
docinfo = extern
morphology = none
min_word_len = 1
min_prefix_len = 0
html_strip = 1
html_remove_elements = style, script
ngram_len = 1
ngram_chars = U+3000..U+2FA1F
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
preopen = 1
min_infix_len = 1
}
#增量索引
index items_delta : items {
source = items_delta
path = /usr/local/sphinx/var/data/items-delta
}
#分布式索引
index master {
type = distributed
local = items
local = items_delta
}
indexer {
mem_limit = 256M
}
searchd {
listen = 9312
listen = 9306:mysql41 #Used for SphinxQL
log = /usr/local/sphinx/var/log/searchd.log
query_log = /usr/local/sphinx/var/log/query.log
compat_sphinxql_magics = 0
attr_flush_period = 600
mva_updates_pool = 16M
read_timeout = 5
max_children = 0
dist_threads = 2
pid_file = /usr/local/sphinx/var/log/searchd.pid
max_matches = 1000
seamless_rotate = 1
preopen_indexes = 1
unlink_old = 1
workers = threads # for RT to work
binlog_path = /usr/local/sphinx/var/data
}
9.sphinx创建索引
./indexer -c /usr/local/sphinx/etc/sphinx.conf --all #启动sphinx ./searchd -c /usr/local/sphinx/etc/sphinx.conf #停止Searchd: ./searchd -c /usr/local/sphinx/etc/sphinx.conf --stop #查看Searchd状态: ./searchd -c /usr/local/sphinx/etc/sphinx.conf --status
10.简单测试
$key = "主从备份";
$index = "items";
$so = scws_new();
$so->set_charset('utf-8');
$so->add_dict(ini_get('scws.default.fpath') . '/dict.utf8.xdb');
$so->set_rule(ini_get('scws.default.fpath') . 'rules.utf8.ini');
$so->set_ignore(true);
$so->set_multi(false);
$so->set_duality(false);
// 自定义词库
// $so->add_dict('./dd.txt',SCWS_XDICT_TXT);
$so->send_text($key);
$words_array = $so->get_result();
$words = "";
foreach($words_array as $v)
{
$words = $words.'|('.$v['word'].')';
}
//加入全词
#$words = '('.$key.')'.$words;
$words = trim($words,'|');
$so->close();
echo '<p>输入:'.$key.'</p>';
echo '<p>分词:'.$words.'</p>';
$sc = new SphinxClient();
$sc->SetServer('127.0.0.1',9312);
#$sc->SetMatchMode(SPH_MATCH_ALL);
$sc->SetMatchMode(SPH_MATCH_EXTENDED);
$sc->SetArrayResult(TRUE);
$res = $sc->Query($words,$index);
print_r($res);
以上所述就是小编给大家介绍的《php用swcs中文分词+sphinx实现全文检索》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 如何实现全文检索?
- lucene全文检索基础
- 全文检索引擎(三)---原理剖析
- 如何实现全文检索功能之搜索之路
- Nov 6 - 使用PostgreSQL进行中文全文检索
- sphinx结合scws的mysql全文检索
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Design Patterns
Elisabeth Freeman、Eric Freeman、Bert Bates、Kathy Sierra、Elisabeth Robson / O'Reilly Media / 2004-11-1 / USD 49.99
You're not alone. At any given moment, somewhere in the world someone struggles with the same software design problems you have. You know you don't want to reinvent the wheel (or worse, a flat tire),......一起来看看 《Head First Design Patterns》 这本书的介绍吧!