• php+中文分词scws+sphinx+mysql打造千万级数据全文搜索


    Sphinx是由俄罗斯人Andrew Aksyonoff开发的一个全文检索引擎。意图为其他应用提供高速、低空间占用、高结果 相关度的全文搜索功能。Sphinx可以非常容易的与SQL数据库和脚本语言集成。当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从标准输入读取特定格式 的XML数据。
    Sphinx创建索引的速度为:创建100万条记录的索引只需3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。
    Sphinx的特性如下:
    a)  高速的建立索引(在当代CPU上,峰值性能可达到10 MB/秒);
    b)  高性能的搜索(在2 – 4GB 的文本数据上,平均每次检索响应时间小于0.1秒);
    c)  可处理海量数据(目前已知可以处理超过100 GB的文本数据, 在单一CPU的系统上可处理100 M 文档);
    d)  提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法;
    e)  支持分布式搜索;
    f)  支持短语搜索
    g)  提供文档摘要生成
    h)  可作为MySQL的存储引擎提供搜索服务;
    i)  支持布尔、短语、词语相似度等多种检索模式;
    j)  文档支持多个全文检索字段(最大不超过32个);
    k)  文档支持多个额外的属性信息(例如:分组信息,时间戳等);
    l)  支持断词;
    虽然mysql的MYISAM提供全文索引,但是性能却不敢让人恭维


    开始搭建

    系统环境:centos6.5+php5.6+apache+MySQL

    1、安装依赖包

    [php] view plain copy
     
    1. yum -y install make gcc g++ gcc-c++ libtool autoconf automake imake php-devel mysql-devel libxml2-devel expat-devel  


    2、安装Sphinx

    [php] view plain copy
     
    1. yum install expat expat-devel  
    2. wget -c http://sphinxsearch.com/files/sphinx-2.0.7-release.tar.gz  
    3. tar zxvf sphinx-2.0.7-release.tar.gz  
    4. cd sphinx-2.0.7-release  
    5. ./configure --prefix=/usr/local/sphinx  --with-mysql --with-libexpat --enable-id64  
    6. make && make install  

    3、安装libsphinxclient,PHP扩展用到

    [php] view plain copy
     
    1. cd api/libsphinxclient  
    2. ./configure --prefix=/usr/local/sphinx/libsphinxclient  
    3. make && make install  


    4、安装Sphinx的PHP扩展:我的是5.6需装sphinx-1.3.3.tgz,如果是php5.4以下可sphinx-1.3.0.tgz

    [php] view plain copy
     
    1. wget -c http://pecl.php.net/get/sphinx-1.3.3.tgz  
    2. tar zxvf sphinx-1.3.3.tgz  
    3. cd sphinx-1.3.3  
    4. phpize  
    5. ./configure --with-sphinx=/usr/local/sphinx/libsphinxclient/ --with-php-config=/usr/bin/php-config  
    6. make && make install  
    7. 成功后会提示:  
    8. Installing shared extensions:     /usr/lib64/php/modules/  
    9.   
    10.   
    11. echo "[Sphinx]" >> /etc/php.ini  
    12. echo "extension = sphinx.so" >> /etc/php.ini  
    13. #重启apache  
    14. service httpd restart  


    5、创建测试数据

    [php] view plain copy
     
    1. CREATE TABLE IF NOT EXISTS `items` (  
    2.   `id` int(11) NOT NULL AUTO_INCREMENT,  
    3.   `title` varchar(255) NOT NULL,  
    4.   `content` text NOT NULL,  
    5.   `created` datetime NOT NULL,  
    6.   PRIMARY KEY (`id`)  
    7. ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='全文检索测试的数据表' AUTO_INCREMENT=11 ;  
    8.   
    9. INSERT INTO `items` (`id`, `title`, `content`, `created`) VALUES  
    10. (1, 'linux mysql集群安装', 'MySQL Cluster 是MySQL 适合于分布式计算环境的高实用、可拓展、高性能、高冗余版本', '2016-09-07 00:00:00'),  
    11. (2, 'mysql主从复制', 'mysql主从备份(复制)的基本原理 mysql支持单向、异步复制,复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器', '2016-09-06 00:00:00'),  
    12. (3, 'hello', 'can you search me?', '2016-09-05 00:00:00'),  
    13. (4, 'mysql', 'mysql is the best database?', '2016-09-03 00:00:00'),  
    14. (5, 'mysql索引', '关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车', '2016-09-01 00:00:00'),  
    15. (6, '集群', '关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车', '0000-00-00 00:00:00'),  
    16. (9, '复制原理', 'redis也有复制', '0000-00-00 00:00:00'),  
    17. (10, 'redis集群', '集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规则放入多个不同的服务器节点,来降低单节点服务器的压力', '0000-00-00 00:00:00');  
    18.   
    19. CREATE TABLE IF NOT EXISTS `sph_counter` (  
    20.   `counter_id` int(11) NOT NULL,  
    21.   `max_doc_id` int(11) NOT NULL,  
    22.   PRIMARY KEY (`counter_id`)  
    23. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='增量索引标示的计数表';  

    以下采用"Main + Delta" ("主索引"+"增量索引")的索引策略,使用Sphinx自带的一元分词。

    6、Sphinx配置:注意修改数据源配置信息

    [php] view plain copy
     
    1. vi /usr/local/sphinx/etc/sphinx.conf  
    2. source items {  
    3.     type = mysql  
    4.     sql_host = localhost  
    5.     sql_user = root  
    6.     sql_pass = 123456  
    7.     sql_db = sphinx_items  
    8.       
    9.     sql_query_pre = SET NAMES utf8  
    10.     sql_query_pre = SET SESSION query_cache_type = OFF  
    11.     sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM items  
    12.       
    13.     sql_query_range = SELECT MIN(id), MAX(id) FROM items   
    14.                             WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)  
    15.     sql_range_step = 1000  
    16.     sql_ranged_throttle = 1000  
    17.   
    18.     sql_query = SELECT id, title, content, created, 0 as deleted FROM items   
    19.                     WHERE id<=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)   
    20.                                 AND id >= $start AND id <= $end    
    21.       
    22.     sql_attr_timestamp = created  
    23.     sql_attr_bool = deleted  
    24. }  
    25.   
    26. source items_delta : items {  
    27.     sql_query_pre = SET NAMES utf8  
    28.     sql_query_range = SELECT MIN(id), MAX(id) FROM items   
    29.                             WHERE id > (SELECT max_doc_id FROM sph_counter WHERE counter_id=1)  
    30.     sql_query = SELECT id, title, content, created, 0 as deleted FROM items   
    31.                     WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 )   
    32.                         AND id >= $start AND id <= $end  
    33.     sql_query_post_index = set @max_doc_id :=(SELECT max_doc_id FROM sph_counter WHERE counter_id=1)  
    34.     sql_query_post_index = REPLACE INTO sph_counter SELECT 2, IF($maxid, $maxid, @max_doc_id)  
    35. }  
    36. #主索引  
    37. index items {  
    38.     source = items  
    39.     path = /usr/local/sphinx/var/data/items  
    40.     docinfo = extern  
    41.     morphology = none  
    42.     min_word_len = 1  
    43.     min_prefix_len = 0  
    44.     html_strip = 1  
    45.     html_remove_elements = style, script  
    46.     ngram_len = 1  
    47.     ngram_chars = U+3000..U+2FA1F  
    48.     charset_type = utf-8  
    49.     charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F  
    50.     preopen = 1     
    51.     min_infix_len = 1  
    52. }  
    53.   
    54. #增量索引  
    55. index items_delta : items {  
    56.     source = items_delta  
    57.     path = /usr/local/sphinx/var/data/items-delta  
    58. }  
    59.   
    60. #分布式索引  
    61. index master {  
    62.     type = distributed  
    63.     local = items  
    64.     local = items_delta  
    65. }  
    66.   
    67. indexer {  
    68.     mem_limit = 256M  
    69. }  
    70.   
    71. searchd {  
    72.     listen                   = 9312  
    73.     listen                   = 9306:mysql41 #Used for SphinxQL  
    74.     log                      = /usr/local/sphinx/var/log/searchd.log  
    75.     query_log          = /usr/local/sphinx/var/log/query.log  
    76.     compat_sphinxql_magics   = 0  
    77.     attr_flush_period                = 600  
    78.     mva_updates_pool   = 16M  
    79.     read_timeout           = 5  
    80.     max_children           = 0  
    81.     dist_threads             = 2   
    82.     pid_file                    = /usr/local/sphinx/var/log/searchd.pid  
    83.     max_matches          = 1000  
    84.     seamless_rotate       = 1  
    85.     preopen_indexes     = 1  
    86.     unlink_old               = 1  
    87.     workers                  = threads # for RT to work  
    88.     binlog_path            = /usr/local/sphinx/var/data  
    89.       
    90. }  

    保存退出

    7、Sphinx创建索引

    [php] view plain copy
     
    1. #第一次需重建索引:  
    2. [root@localhost bin]# ./indexer -c /usr/local/sphinx/etc/sphinx.conf --all  
    3. Sphinx 2.0.7-id64-release (r3759)  
    4. Copyright (c) 2001-2012, Andrew Aksyonoff  
    5. Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)  
    6.   
    7. using config file '/usr/local/sphinx/etc/sphinx.conf'...  
    8. indexing index 'items'...  
    9. collected 8 docs, 0.0 MB  
    10. sorted 0.0 Mhits, 100.0% done  
    11. total 8 docs, 1121 bytes  
    12. total 1.017 sec, 1101 bytes/sec, 7.86 docs/sec  
    13. indexing index 'items_delta'...  
    14. collected 0 docs, 0.0 MB  
    15. total 0 docs, 0 bytes  
    16. total 1.007 sec, 0 bytes/sec, 0.00 docs/sec  
    17. skipping non-plain index 'master'...  
    18. total 4 reads, 0.000 sec, 0.7 kb/call avg, 0.0 msec/call avg  
    19. total 14 writes, 0.001 sec, 0.5 kb/call avg, 0.1 msec/call avg  
    20. #启动sphinx  
    21. [root@localhost bin]# ./searchd -c /usr/local/sphinx/etc/sphinx.conf  
    22. Sphinx 2.0.7-id64-release (r3759)  
    23. Copyright (c) 2001-2012, Andrew Aksyonoff  
    24. Copyright (c) 2008-2012, Sphinx Technologies Inc (http://sphinxsearch.com)  
    25.   
    26. using config file '/usr/local/sphinx/etc/sphinx.conf'...  
    27. listening on all interfaces, port=9312  
    28. listening on all interfaces, port=9306  
    29. precaching index 'items'  
    30. precaching index 'items_delta'  
    31. rotating index 'items_delta': success  
    32. precached 2 indexes in 0.012 sec  
    33. #查看进程  
    34. [root@localhost bin]# ps -ef | grep searchd  
    35. root     30431     1  0 23:59 ?        00:00:00 ./searchd -c /usr/local/sphinx/etc/sphinx.conf  
    36. root     30432 30431  0 23:59 ?        00:00:00 ./searchd -c /usr/local/sphinx/etc/sphinx.conf  
    37. root     30437  1490  0 23:59 pts/0    00:00:00 grep searchd  
    38. #停止Searchd:  
    39. ./searchd -c /usr/local/sphinx/etc/sphinx.conf --stop  
    40. #查看Searchd状态:  
    41. ./searchd -c /usr/local/sphinx/etc/sphinx.conf --status  

    索引更新及使用说明
    "增量索引"每N分钟更新一次.通常在每天晚上低负载的时进行一次索引合并,同时重新建立"增量索引"。当然"主索引"数据不多的话,也可以直接重新建立"主索引"。
    API搜索的时,同时使用"主索引"和"增量索引",这样可以获得准实时的搜索数据.本文的Sphinx配置将"主索引"和"增量索引"放到分布式索引master中,因此只需查询分布式索引"master"即可获得全部匹配数据(包括最新数据)。

    索引的更新与合并的操作可以放到cron job完成:

    [php] view plain copy
     
    1. crontab -e  
    2. */1 * * * *  /usr/local/sphinx/shell/delta_index_update.sh  
    3. 0 3 * * *    /usr/local/sphinx/shell/merge_daily_index.sh  
    4. crontab -l  

    cron job所用的shell脚本例子:

    delta_index_update.sh:

    [php] view plain copy
     
    1. #!/bin/bash  
    2. /usr/local/sphinx/bin/indexer -c /usr/local/sphinx/etc/sphinx.conf --rotate items_delta > /dev/null 2>&1  

    merge_daily_index.sh:

    [php] view plain copy
     
    1. #!/bin/bash  
    2. indexer=`which indexer`  
    3. mysql=`which mysql`  
    4.   
    5. QUERY="use sphinx_items;select max_doc_id from sph_counter where counter_id = 2 limit 1;"  
    6. index_counter=$($mysql -h192.168.1.198 -uroot -p123456 -sN -e "$QUERY")  
    7.   
    8. #merge "main + delta" indexes  
    9. $indexer -c /usr/local/sphinx/etc/sphinx.conf --rotate --merge items items_delta --merge-dst-range deleted 0 0 >> /usr/local/sphinx/var/index_merge.log 2>&1  
    10.   
    11. if [ "$?" -eq 0 ]; then  
    12.     ##update sphinx counter  
    13.     if [ ! -z $index_counter ]; then  
    14.         $mysql -h192.168.1.198 -uroot -p123456 -Dsphinx_items -e "REPLACE INTO sph_counter VALUES (1, '$index_counter')"  
    15.     fi  
    16.     ##rebuild delta index to avoid confusion with main index  
    17.     $indexer -c /usr/local/sphinx/etc/sphinx.conf --rotate items_delta >> /usr/local/sphinx/var/rebuild_deltaindex.log 2>&1  
    18. fi  


    8、php中文分词scws安装:注意扩展的版本和php的版本

    [php] view plain copy
     
    1. wget -c http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2  
    2. tar jxvf scws-1.2.3.tar.bz2  
    3. cd scws-1.2.3  
    4. ./configure --prefix=/usr/local/scws  
    5. make && make install  


    9、scws的PHP扩展安装:

    [php] view plain copy
     
    1. cd ./phpext  
    2. phpize   
    3. ./configure  
    4. make && make install  
    5. echo "[scws]" >> /etc/php.ini  
    6. echo "extension = scws.so" >> /etc/php.ini  
    7. echo "scws.default.charset = utf-8" >> /etc/php.ini  
    8. echo "scws.default.fpath = /usr/local/scws/etc/" >> /etc/php.ini  


    10、词库安装:

    [php] view plain copy
     
    1. wget http://www.xunsearch.com/scws/down/scws-dict-chs-utf8.tar.bz2  
    2. tar jxvf scws-dict-chs-utf8.tar.bz2 -C /usr/local/scws/etc/  
    3. chown www:www /usr/local/scws/etc/dict.utf8.xdb  

    11、php使用Sphinx+scws测试例子
    在Sphinx源码API中,有好几种语言的API调用.其中有一个是sphinxapi.php。
    不过以下的测试使用的是Sphinx的PHP扩展.具体安装见本文开头的Sphinx安装部分。
    测试用的搜索类Search.php:注意修改getDBConnection()信息为自己的

    [php] view plain copy
     
    1. <?php  
    2. class Search {  
    3.     /** 
    4.      * @var SphinxClient  
    5.     **/  
    6.     protected $client;  
    7.     /** 
    8.      * @var string 
    9.     **/  
    10.     protected $keywords;  
    11.     /** 
    12.      * @var resource 
    13.     **/  
    14.     private static $dbconnection = null;  
    15.       
    16.     /** 
    17.      * Constructor 
    18.      **/  
    19.     public function __construct($options = array()) {  
    20.         $defaults = array(  
    21.             'query_mode' => SPH_MATCH_EXTENDED2,  
    22.             'sort_mode' => SPH_SORT_EXTENDED,  
    23.             'ranking_mode' => SPH_RANK_PROXIMITY_BM25,  
    24.             'field_weights' => array(),  
    25.             'max_matches' => 1000,  
    26.             'snippet_enabled' => true,  
    27.             'snippet_index' => 'items',  
    28.             'snippet_fields' => array(),   
    29.         );  
    30.         $this->options = array_merge($defaults, $options);  
    31.         $this->client = new SphinxClient();  
    32.         //$this->client->setServer("192.168.1.198", 9312);  
    33.         $this->client->setMatchMode($this->options['query_mode']);  
    34.         if ($this->options['field_weights'] !== array()) {  
    35.             $this->client->setFieldWeights($this->options['field_weights']);  
    36.         }  
    37.         /* 
    38.         if ( in_array($this->options['query_mode'], [SPH_MATCH_EXTENDED2,SPH_MATCH_EXTENDED]) ) { 
    39.             $this->client->setRankingMode($this->options['ranking_mode']); 
    40.         } 
    41.         */  
    42.     }  
    43.      
    44.     /** 
    45.      * Query 
    46.      * 
    47.      * @param string  $keywords 
    48.      * @param integer $offset 
    49.      * @param integer $limit 
    50.      * @param string  $index 
    51.      * @return array 
    52.      **/  
    53.     public function query($keywords, $offset = 0, $limit = 10, $index = '*') {  
    54.         $this->keywords = $keywords;  
    55.         $max_matches = $limit > $this->options['max_matches'] ? $limit : $this->options['max_matches'];  
    56.         $this->client->setLimits($offset, $limit, $max_matches);  
    57.         $query_results = $this->client->query($keywords, $index);  
    58.   
    59.         if ($query_results === false) {  
    60.             $this->log('error:' . $this->client->getLastError());  
    61.         }  
    62.                  
    63.         $res = [];  
    64.         if ( empty($query_results['matches']) ) {  
    65.             return $res;  
    66.         }  
    67.         $res['total'] = $query_results['total'];  
    68.         $res['total_found'] = $query_results['total_found'];  
    69.         $res['time'] = $query_results['time'];  
    70.         $doc_ids = array_keys($query_results['matches']);  
    71.         unset($query_results);  
    72.         $res['data'] = $this->fetch_data($doc_ids);  
    73.         if ($this->options['snippet_enabled']) {  
    74.             $this->buildExcerptRows($res['data']);  
    75.         }  
    76.           
    77.         return $res;  
    78.     }  
    79.       
    80.     /** 
    81.      * custom sorting  
    82.      *  
    83.      * @param string $sortBy 
    84.      * @param int $mode 
    85.      * @return bool 
    86.      **/  
    87.     public function setSortBy($sortBy = '', $mode = 0) {  
    88.         if ($sortBy) {  
    89.             $mode = $mode ?: $this->options['sort_mode'];  
    90.             $this->client->setSortMode($mode, $sortBy);  
    91.         } else {  
    92.             $this->client->setSortMode(SPH_SORT_RELEVANCE);  
    93.         }  
    94.     }  
    95.       
    96.     /** 
    97.      * fetch data based on matched doc_ids 
    98.      *  
    99.      * @param array $doc_ids 
    100.      * @return array 
    101.      **/      
    102.     protected function fetch_data($doc_ids) {  
    103.         $ids = implode(',', $doc_ids);  
    104.         $queries = self::getDBConnection()->query("SELECT * FROM items WHERE id in ($ids)", PDO::FETCH_ASSOC);  
    105.         return iterator_to_array($queries);  
    106.     }  
    107.       
    108.     /** 
    109.      * build excerpts for data 
    110.      *  
    111.      * @param array $rows 
    112.      * @return array 
    113.      **/   
    114.     protected function buildExcerptRows(&$rows) {  
    115.         $options = array(  
    116.             'before_match' => '<b style="color:red">',  
    117.             'after_match'  => '</b>',  
    118.             'chunk_separator' => '...',  
    119.             'limit'    => 256,  
    120.             'around'   => 3,  
    121.             'exact_phrase' => false,  
    122.             'single_passage' => true,  
    123.             'limit_words' => 5,  
    124.         );  
    125.         $scount = count($this->options['snippet_fields']);  
    126.         foreach ($rows as &$row) {  
    127.             foreach ($row as $fk => $item) {  
    128.                 if (!is_string($item) || ($scount && !in_array($fk, $this->options['snippet_fields'])) ) continue;  
    129.                 $item = preg_replace('/[ ]+/', '', strip_tags($item));  
    130.                 $res = $this->client->buildExcerpts(array($item), $this->options['snippet_index'], $this->keywords, $options);  
    131.                 $row[$fk] = $res === false ? $item : $res[0];  
    132.             }  
    133.         }          
    134.         return $rows;  
    135.     }  
    136.       
    137.     /** 
    138.      * database connection 
    139.      * 
    140.      * @return resource 
    141.      **/   
    142.     private static function getDBConnection() {  
    143.         $dsn = 'mysql:host=192.168.1.198;dbname=sphinx_items';  
    144.         $user = 'root';  
    145.         $pass = '123456';  
    146.         if (!self::$dbconnection) {  
    147.             try {  
    148.                 self::$dbconnection = new PDO($dsn, $user, $pass);  
    149.             } catch (PDOException $e) {  
    150.                 die('Connection failed: ' . $e->getMessage());  
    151.             }  
    152.         }  
    153.         return self::$dbconnection;  
    154.     }  
    155.   
    156.     /** 
    157.      * Chinese words segmentation 
    158.      * 
    159.      **/  
    160.     public function wordSplit($keywords) {  
    161.         $fpath = ini_get('scws.default.fpath');  
    162.         $so = scws_new();  
    163.         $so->set_charset('utf-8');  
    164.         $so->add_dict($fpath . '/dict.utf8.xdb');  
    165.         //$so->add_dict($fpath .'/custom_dict.txt', SCWS_XDICT_TXT);  
    166.         $so->set_rule($fpath . '/rules.utf8.ini');  
    167.         $so->set_ignore(true);  
    168.         $so->set_multi(false);  
    169.         $so->set_duality(false);  
    170.         $so->send_text($keywords);  
    171.         $words = [];  
    172.         $results =  $so->get_result();  
    173.         foreach ($results as $res) {  
    174.             $words[] = '(' . $res['word'] . ')';  
    175.         }  
    176.         $words[] = '(' . $keywords . ')';  
    177.         return join('|', $words);  
    178.     }  
    179.       
    180.     /** 
    181.      * get current sphinx client 
    182.      * 
    183.      * @return resource 
    184.      **/  
    185.     public function getClient() {  
    186.         return $this->client;  
    187.     }  
    188.     /** 
    189.      * log error 
    190.      **/  
    191.     public function log($msg) {  
    192.         // log errors here  
    193.         //echo $msg;  
    194.     }      
    195.     /** 
    196.      * magic methods 
    197.      **/  
    198.     public function __call($method, $args) {  
    199.         $rc = new ReflectionClass('SphinxClient');  
    200.         if ( !$rc->hasMethod($method) ) {  
    201.             throw new Exception('invalid method :' . $method);  
    202.         }  
    203.         return call_user_func_array(array($this->client, $method), $args);  
    204.     }  
    205. }  


    测试文件test.php:

    [php] view plain copy
     
    1. <?php  
    2. require('Search.php');  
    3. $s = new Search([  
    4.         'snippet_fields' => ['title', 'content'],  
    5.         'field_weights' => ['title' => 20, 'content' => 10],  
    6.     ]);  
    7. $s->setSortMode(SPH_SORT_EXTENDED, 'created desc,@weight desc');  
    8. //$s->setSortBy('created desc,@weight desc');  
    9. $words = $s->wordSplit("mysql集群");//先分词 结果:(mysql)|(mysql集群)  
    10. //print_r($words);exit;  
    11. $res = $s->query($words, 0, 10, 'master');  
    12. echo '<pre/>';print_r($res);  

    测试结果:

    12、SphinxQL测试

    要使用SphinxQL需要在Searchd的配置里面增加相应的监听端口(参考上文配置)。

    [php] view plain copy
     
    1. [root@localhost bin]# mysql -h127.0.0.1 -P9306 -uroot -p  
    2. Enter password:  
    3. Welcome to the MySQL monitor.  Commands end with ; or g.  
    4. Your MySQL connection id is 1  
    5. Server version: 2.0.7-id64-release (r3759)  
    6.   
    7. Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.  
    8.   
    9. Oracle is a registered trademark of Oracle Corporation and/or its  
    10. affiliates. Other names may be trademarks of their respective  
    11. owners.  
    12.   
    13. Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.  
    14.   
    15. mysql> show global variables;  
    16. +----------------------+---------+  
    17. | Variable_name        | Value   |  
    18. +----------------------+---------+  
    19. | autocommit           | 1       |  
    20. | collation_connection | libc_ci |  
    21. | query_log_format     | plain   |  
    22. | log_level            | info    |  
    23. +----------------------+---------+  
    24. 4 rows in set (0.00 sec)  
    25.   
    26. mysql> desc items;  
    27. +---------+-----------+  
    28. | Field   | Type      |  
    29. +---------+-----------+  
    30. | id      | bigint    |  
    31. | title   | field     |  
    32. | content | field     |  
    33. | created | timestamp |  
    34. | deleted | bool      |  
    35. +---------+-----------+  
    36. 5 rows in set (0.00 sec)  
    37.   
    38. mysql> select * from master where match ('mysql集群') limit 10;  
    39. +------+---------+---------+  
    40. | id   | created | deleted |  
    41. +------+---------+---------+  
    42. |    1 |    2016 |       0 |  
    43. |    6 |       0 |       0 |  
    44. +------+---------+---------+  
    45. 2 rows in set (0.00 sec)  
    46.   
    47. mysql> show meta;  
    48. +---------------+-------+  
    49. | Variable_name | Value |  
    50. +---------------+-------+  
    51. | total         | 2     |  
    52. | total_found   | 2     |  
    53. | time          | 0.006 |  
    54. | keyword[0]    | mysql |  
    55. | docs[0]       | 5     |  
    56. | hits[0]       | 15    |  
    57. | keyword[1]    | 集    |  
    58. | docs[1]       | 3     |  
    59. | hits[1]       | 4     |  
    60. | keyword[2]    | 群    |  
    61. | docs[2]       | 3     |  
    62. | hits[2]       | 4     |  
    63. +---------------+-------+  
    64. 12 rows in set (0.00 sec)  
    65.   
    66. mysql>  
  • 相关阅读:
    Python函数参数学习笔记
    Python基础笔记
    winform碎片
    常用sql语句
    《零基础入门学习Python》学习过程笔记【021匿名函数】
    统计下边这个长字符串中各个字符出现的次数并找到小甲鱼送给大家的一句话
    《零基础入门学习Python》学习过程笔记【020函数的局部变量和全全局变量内部函数和闭包】
    编写一个函数,分别统计出传入字符串参数(可能不止一个参数)的英文字母,空格,数字和其他字符的个数
    写一个函数,判断一个字符串是否为回文联
    《零基础入门学习Python》学习过程笔记【019函数返回值问题】
  • 原文地址:https://www.cnblogs.com/cnsanshao/p/7003960.html
Copyright © 2020-2023  润新知