内容简介: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全文检索
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
大数据系统构建
Nathan Marz、James Warren / 马延辉、向磊、魏东琦 / 机械工业出版社 / 2017-1 / 79.00
随着社交网络、网络分析和智能型电子商务的兴起,传统的数据库系统显然已无法满足海量数据的管理需求。 作为一种新的处理模式,大数据系统应运而生,它使用多台机器并行工作,能够对海量数据进行存储、处理、分析,进而帮助用户从中提取对优化流程、实现高增长率的有用信息,做更为精准有效的决策。 但不可忽略的是,它也引入了大多数开发者并不熟悉的、困扰传统架构的复杂性问题。 本书将教你充分利用集群硬件优势的La......一起来看看 《大数据系统构建》 这本书的介绍吧!