内容简介: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全文检索
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ruby Cookbook
Lucas Carlson、Leonard Richardson / O'Reilly Media / 2006-7-29 / USD 49.99
Do you want to push Ruby to its limits? The "Ruby Cookbook" is the most comprehensive problem-solving guide to today's hottest programming language. It gives you hundreds of solutions to real-world pr......一起来看看 《Ruby Cookbook》 这本书的介绍吧!