官方文档: http://sphinxsearch.com/docs/sphinx3.html

Sphinx是一款基于SQL的高性能全文检索引擎,Sphinx的性能在众多全文检索引擎中也是数一数二的,利用Sphinx,我们可以完成比数据库本身更专业的搜索功能,而且可以有很多针对性的性能优化。

Sphinx的特点

安装

sudo apt-get install libmysqlclient-dev libpq-dev unixodbc-dev
sudo apt-get install libmariadb-client-lgpl-dev-compat
sudo apt install sphinxsearch

Sphinx工作流程图

img

Sphinx的整个工作流程就是Indexer程序到数据库里面提取数据,对数据进行分词,然后根据生成的分词生成单个或多个索引,并将它们传递给searchd程序。然后客户端可以通过API调用进行搜索。

sphinx的配置

source:数据源,数据是从什么地方来的。
index:索引,当有数据源之后,从数据源处构建索引。索引实际上就是相当于一个字典检索。有了整本字典内容以后,才会有字典检索。
searchd:提供搜索查询服务。它一般是以deamon的形式运行在后台的。
indexer:构建索引的服务。当要重新构建索引的时候,就是调用indexer这个命令。
attr:属性,属性是存在索引中的,它不进行全文索引,但是可以用于过滤和排序。
source basic{
    type          = mysql
    sql_host        = 127.0.0.1
    sql_user        = root
    sql_pass        = root
    sql_db         = test
    sql_port        = 3306 
    sql_query_pre      = SET NAMES utf8
}
source productst : basic{
    sql_query        = \
        SELECT t.id,t.uid,t.title,t.description \
        where t.approved=1 and t.id>=$start and t.id<=$end
    
    #对表进行分区
    sql_query_range = SELECT min_id ,max_id FROM `sphinx_part` WHERE part_id = 1 LIMIT 1
    #sql_range_step = 1000000
    sql_attr_uint           = uid
    sql_attr_string            = title
    sql_attr_multi            = uint payment_type from field payment_type
    sql_attr_timestamp         = tempdate
}
index search_productst{
        type                    = plain
        source                  = productst
        path                    = /srv/sphinxsearch/data/search_productst
        docinfo                 = extern
        mlock                   = 0
        morphology              = none
        # 最小索引词长度,小于这个长度的词不会被索引。
        min_word_len            = 3
        # 字符集编码类型
        charset_type            = utf-8
        # 字符表和大小写转换规则
        # 'utf-8' default value is
        charset_table        = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F

        ## html标记清理,是否从输出全文数据中去除HTML标记。
        html_strip        = 0
}


searchd
{
    listen                = 9312
    listen                = 9306:mysql41
    log                    = /var/log/sphinxsearch/searchd.log
    query_log            = /var/log/sphinxsearch/query.log
    read_timeout        = 5
    client_timeout        = 10
    max_children        = 60
    pid_file            = /var/run/sphinxsearch/searchd.pid
    #max_matches        = 10000
    seamless_rotate        = 1
    preopen_indexes        = 1
    unlink_old            = 1
    # attr_flush_period    = 900
    # ondisk_dict_default    = 1
    mva_updates_pool    = 1M
    max_packet_size        = 16M
    max_filters            = 256
    max_filter_values    = 4096
    max_batch_queries    = 32
    workers                = threads # for RT to work
    collation_server    = utf8_general_ci
    #compat_sphinxql_magics    = 0
    
    #并发查询线程数
    dist_threads         = 7
}

常用的四种形式:
sql_field_string = title #指定字符型字段,可全文搜索,可返回原始文本信息
sql_attr_uint = year #无符号整型属性
sql_attr_string = description #指定字符型属性,只存储不参与搜索
sql_attr_multi = areas #多值字段,值以逗号分开。

创建索引

#创建所有索引
indexer --all
#创建search_productst索引
indexer search_productst

PHP查询sphinx

  require('SphinxClient.php');
  //创建Sphinx的客户端接口对象
  $cl = new SphinxClient();
 
  //设置连接Sphinx主机名与端口
  $cl->SetServer('192.168.99.99',9312);
  /*
 
  //可选,为每一个全文检索字段设置权重,主要根据你在sql_query中定义的字段的顺序,Sphinx系统以后会调整,可以按字段名称来设定权重
  $cl->SetWeights ( array ( 100, 1 ) );
 
  //设定搜索模式,SPH_MATCH_ALL,SPH_MATCH_ANY,SPH_MATCH_BOOLEAN,SPH_MATCH_EXTENDED,SPH_MATCH_PHRASE
  $cl->SetMatchMode(SPH_MATCH_ALL);
 
  //设定过滤条件$attribute是属性名,相当于字段名(用SPH_MATCH_EXTENDED时),$value是值,$exclude是布尔型,
  //当为true时,相当于$attribute!=$value,默认值是false
  $cl->SetFilter($attribute, $values, $exclude);
 
  //设定group by
  //根据分组方法,匹配的记录集被分流到不同的组,每个组都记录着组的匹配记录数以及根据当前排序方法本组中的最佳匹配记录。
  //最后的结果集包含各组的一个最佳匹配记录,和匹配数量以及分组函数值
  //结果集分组可以采用任意一个排序语句,包括文档的属性以及sphinx的下面几个内部属性
  //@id--匹配文档ID
  //@weight, @rank, @relevance--匹配权重
  //@group--group by 函数值
  //@count--组内记录数量
  //$groupsort的默认排序方法是@group desc,就是按分组函数值大小倒序排列
  $cl->SetGroupBy($attribute, $func, $groupsort);
 
  //设定order by的内容,第一个参数是排序方法名,值有
  // SPH_SORT_RELEVANCE, SPH_SORT_ATTR_DESC,SPH_SORT_ATTR_ASC, SPH_SORT_TIME_SEGMENTS, SPH_SORT_EXTENDED
  //$sortby的值如"HITS desc"
  $cl->SetSortMode(SPH_SORT_EXTENDED, $sortby);
 
  //set count-distinct attribute for group-by queries,$distinct为字符串
  $cl->SetGroupDistinct ( $distinct );
 
  //相当于mysql的limit $offset,$limit
  $cl->SetLimits($start,$limit)
 
  //$q是查询的关键字,$index是索引名称,当等于*时表查询所有索引*/
  $index = 'search_product_tag';
  $q = 'Gown';
  $res = $cl->Query ( $q, $index );

以上代码输出

string(0) ""
array(10) {
  ["error"]=>
  string(0) ""
  ["warning"]=>
  string(0) ""
  ["status"]=>
  int(0)
  ["fields"]=>
  array(1) {
    [0]=>
    string(7) "keyword"
  }
  ["attrs"]=>
  array(2) {
    ["words"]=>
    int(7)
    ["uri"]=>
    int(7)
  }
  ["matches"]=>
  array(4) {
    [8]=>
    array(2) {
      ["weight"]=>
      string(1) "1"
      ["attrs"]=>
      array(2) {
        ["words"]=>
        string(17) "Beading Ball Gown"
        ["uri"]=>
        string(0) ""
      }
    }
    [9]=>
    array(2) {
      ["weight"]=>
      string(1) "1"
      ["attrs"]=>
      array(2) {
        ["words"]=>
        string(15) "Satin Ball Gown"
        ["uri"]=>
        string(0) ""
      }
    }
    [124]=>
    array(2) {
      ["weight"]=>
      string(1) "1"
      ["attrs"]=>
      array(2) {
        ["words"]=>
        string(17) "Taffeta Ball Gown"
        ["uri"]=>
        string(0) ""
      }
    }
    [193]=>
    array(2) {
      ["weight"]=>
      string(1) "1"
      ["attrs"]=>
      array(2) {
        ["words"]=>
        string(22) "Chapel Train Ball Gown"
        ["uri"]=>
        string(0) ""
      }
    }
  }
  ["total"]=>
  string(1) "4"
  ["total_found"]=>
  string(1) "4"
  ["time"]=>
  string(5) "0.000"
  ["words"]=>
  array(1) {
    ["gown"]=>
    array(2) {
      ["docs"]=>
      string(1) "4"
      ["hits"]=>
      string(1) "4"
    }
  }

Sphinx匹配模式

匹配模式说明
SPH_MATCH_ALL匹配所有查询词(默认模式).
SPH_MATCH_ANY匹配查询词中的任意一个.
SPH_MATCH_PHRASE将整个查询看作一个词组,要求按顺序完整匹配.
SPH_MATCH_BOOLEAN将查询看作一个布尔表达式.
SPH_MATCH_EXTENDED将查询看作一个Sphinx内部查询语言的表达式.
SPH_MATCH_FULLSCAN使用完全扫描,忽略查询词汇.
SPH_MATCH_EXTENDED2类似 SPH_MATCH_EXTENDED ,并支持评分和权重.

扩展查询有下面特殊操作符:
操作符OR:hello | world,区配含有hello或world
操作符NOT:hello -world或hello !world,区配包含hello,且不包含world
字段搜索操作符:@title hello @body world,匹配title中有hello及body中有world
字段限位修饰符:@title[5] hello ,匹配title字段前5个词中包含有hello
多字段搜索符:@(title,body) hello,匹配title或body包含有hello
全字段搜索符:@* hello,区配任何一列包含有hello
阀值匹配符:"this is test document number"/3,匹配至少包含有3个词
短语(phrase)搜索符:“hello world”
临近(proximity)搜索符:“hello world”~10,匹配hello与world之间小于10个词
严格有序搜索符:aaa<<bbb<<ccc,匹配aaa,bbb,ccc按顺序出现
字段开始和字段结束修饰符:^hello world$,匹配以hello开始,world为结尾