xunsearch配置文件详解,实例讲解,官网文档看不懂的看这个
- 作者: 刘杰
- 来源: 技术那些事
- 阅读:180
- 发布: 2025-08-14 13:45
- 最后更新: 2025-08-15 18:41

xunsearch 中文名称为迅搜,是采用 C/C++ 基于 xapian 和 scws 开发的全文搜索引擎解决方案,适用于php全文检索、mysql全文检索和各种站内搜索。支持海量数据高速检索,功能强大、简单易用、开源免费!
这个开源项目,我初次使用应该是在2011年,没错2011年的时候,它就已经存在了,那时候应该是刚刚上线不久。具体当时是什么版本,我已经记不清了。只知道当时是我们的领导,告诉我们有这么个东西,研究下能否使用。当时我们公司的项目也是 Yii 框架,正好合适。
于是做了一番调研,发现xunsearch按照文档的说明,几乎就是给我们这种项目量身打造的。开源、性能优秀、资源占用小,安装使用简单。深入调研,安装上,使用之后,发现性能比想象中的还好。而且确实是很简单,无论搭建还是使用。我当时也才是个的初级程序开发,捣鼓了两三天就用上了,这就是最好的证明了。
我看 xunsearch 的文档下面,好多人在吐槽文档不够详细。我并不认同,因为我刚用时候2011年,你就应该能够明白,那时候的文档,甚至还不如现在,我不是也搞定了吗。这种东西光看是远远不够的,必须要实际操作一下,文档上确实不一定能够精确到你用到的每一个细节,但是只要试试,那种"逗号"还是"句号","大写"还是"小写","中划线"还是"下划线"的问题,一试便知。眼高手低,是成为优秀程序员之路上的众多阻碍之一。不要懒!
xunsearch的配置项
ini 配置文件基本规范
项目配置是Xunsearch 项目的核心灵魂,非常重要,通常保存为 .ini 文件。说它重要,是因为,服务端和客户端的配置都需要它,服务端用它来识别内容存储的结构设计。客户端用它来检索数据时候也是必不可少。除此之外,如果不做更深入的开发或者调整,几乎不用再修改任何配置。文件名称(去掉.ini),和配置中的 project.name 保持一直即可,文件名和项目名称,只能用小写字母和下划线。
以分号开头的行表示注释,空行直接被忽略不起任何作用
中括号包围的每个分区均为字段配置,字段个数根据项目的实际需求设定
每个项目必须有并且只能有一个类型类 ID 的主键字段,ID 字段值的字母不区分大小写
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 项目名称,小写字母和下划线组成,"="左右两边的空格不影响
project.name = blog_content
; 字段配置用中括号包裹,名字不一定是id,可以根据实际情况去写,比如:[username]
[id]
; type 类型为 id(也可以是ID,不区分大小写),表明是个主键字段
type = id
下面逐个字段,我会介绍配置项各个项目的基本设计和规范。
配置项规范
项目名称
要求用纯小写字母和下划线组成,长度控制在 2-31 个字符,这也是 xunsearch 服务器内用于保存索引数据的目录名称, 所以同一 xunsearch 服务器内的不同项目名称不可重复。默认为不含后缀的配置文件名, 如:xyz.ini 则项目名默认为 xyz 。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 项目名称,小写字母和下划线组成,"="左右两边的空格不影响
project.name = blog_content
字符集
这里的默认字符集范围涵盖服务端交互时的输入数据、输出数据,实际使用时索引文档、 检索服务器仍可重新指定字符集。这里一般设置为国际通用的 UTF-8 字符集即可。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 默认字符集为 UTF-8
project.default_charset = UTF-8
服务器连接设置
服务端连接参数的格式有三种格式:
- 直接设置端口号,连接的是 localhost 的端口号,如果设置8383,相当于localhost:8383
- 
远程地址:端口号,远程地址可以是IP,也可以是域名,比如:172.21.0.2:8383
- 文件路径,一般指向本地域套接字,本机的 unix_socket 地址,比如:/usr/lib/search/index.sock
如果是本机,可以选择1或者3,测试时候一般用这种。但是生产环境部署,往往服务和客户端是分离的,这就要用到远程地址,所以生产环境用的一般是2。而地址,就可以设置成 docker 的网络或者 vpc 内网地址,或者 SLB 的网关地址,等等。这个具体根据需要使用就好。
注意,这里在进行内容查询时候,php 的 sdk 是没有地方设置服务器的,当然你说你扩展下,就当我没说。XS::class 对象在实例化的时候,只让传一个 ini 文件路径。这样配置起来更方便,否则如果检索内容太多,一项一项设置,光配置就很烦人。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 索引服务端配置,这里配置为远程地址,端口8383
server.index = 172.21.0.2:8383
; 搜索服务端配置,这里配置为远程地址,端口8384
server.search = 172.21.0.2:8384
; 两个服务,对应两个端口,一个是用来写索引的,一个是用来查数据的
注意:官网文档提示,自 1.4.7 版本开始,服务端地址可以使用
;分隔指定多个。 索引更新将同步到所有服务端,而搜索则随机从中挑选一个可用的服务端以达到均横效果。
按照以上说明,可以如此配置多服务端:
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 三个服务端地址,一个端口8383(可以为不同端口)
server.index = 172.21.0.2:8383;172.21.0.3:8383;172.21.0.4:8383
; 三个服务端,端口8384(可以每个端口不一样)
server.search = 172.21.0.2:8384;172.21.0.3:8384;172.21.0.4:8384
; 不同服务器端口设置同为8383和8384,为的是保持一致,不容易弄混,不怕混乱可以设置为不同端口。
用到这种结构,一般用来分摊搜索的访问压力,类似mysql 的读写分离,多个读库共同分摊搜索的压力。一个内容更新时,可以同时更新所有的索引。
字段选项
每个字段根据实际情况指定字段选项,所有选项均有默认值,所以即便不指定任何选项而只有中括号定义的字段, 那也是一个合法的字段,一个配置项可以设置的字段选项包括以下几种:
| 字段类型 | 类型值 | 默认值 | 
|---|---|---|
| type | string/numeric/date/id/title/body | string | 
| index | none/self/mixed/both | none | 
| tokenizer | default/full/none/split()/xlen()/xstep()/scws() | default | 
| cutlen | 任何大于0的数字,单位是字节(汉字为3个字节),0表示不截断 | 0 | 
| weight | 0:不参与权重计算,值越大权重越高, title:5,body:1 | 1 | 
| phrase | yes/no | no | 
| non_bool | yes/no | no | 
type 类型说明
- string 字符型,适用多数情况,也是默认值
- numeric 数值型,包含整型和浮点数,仅当字段需用于以排序或区间检索时才设为该类型,否则请使用 string 即可。(如要检索,还需要索引配置)
- date 日期型,形式为 YYYYmmdd 这样固定的 8 字节,如果没有区间检索或排序需求不建议使用
- id 主键型,确保每条数据具备唯一值,是索引更新和删除的凭据,每个搜索项目必须有且仅有一个 id 字段,该字段的值不区分大小写
- title 标题型,标题或名称字段,至多有一个该类型的字段
- body 内容型,主内容字段, 即本搜索项目中内容最长的字段,至多只有一个该类型字段,本字段不支持字段检索。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 举例说明
[name]
type = string
[sort]
; 加上单独字段索引,可以指定字段检索
index = self
; 设置为数值型,可以进行范围检索,或者排序
type = numeric
; 字段的值整体作为一个检索词
tokenizer = full
index 类型说明
index 索引有 2 种模式:
其一是不标明字段的检索,称之为“混合区检索”。
例如:搜索 XXX YYY 表示在混合区检索,返回的结果可能是 title 也有可能是 body 字段符合匹配;
其二是标明特定字段的“字段检索”。
搜索 title:XXX 则表示仅检索 title 匹配 XXX 的数据。
每个字段可以指定的索引方式的值如下:
- none 不做索引,所有的搜索匹配均与本字段无关,这个字段只用于排序或搜索结果展示用到。
- self 字段索引,可以在搜索时用 field:XXX 来检索本字段
- mixed 混合区索引,不标明字段的默认搜索也可以检索本字段
- both 相当于 self + mixed,两种情况均索引
通常情况默认值为 none ,但 id 型字段默认是 self ,title 型字段是 both ,body 型字段则固定为 mixed 。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 不明确写明时候的默认值
index = none
tokenizer 分词器类型说明
默认为 default 采用内置的功能强大的 scws 分词,适合绝大多数字符串字段。
也可以指定自定义分词器, 格式为 name 或 name(arg) 两种形式,其中 name 是分词器名称,arg 则是传递给分词器构造函数的参数。
自定义分词器需要在 lib/ 目录下编写名为 XSTokenizerName 的分词类并实现接口 XSTokenizer,内置支持的分词器有以下几种:
- default,scws 默认分词,适合绝大多数字段
- full 表示本字段的值整体作为一个检索词,像各种 ID 都适合这种情况
- none 表示本字段没有任何词汇用于索引
- split([ ]) 表示根据参数分割内容,默认参数为空格,若参数以 / 开头并以 / 结尾则 内部调用 preg_split(arg, ..)来分割取词,以支持正则或其它特殊字符分割
- xlen([2]) 表示根据指定参数长度分段取词,如 ABCDEF => AB + CD + EF
- xstep([2]) 表示根据指定参数步长逐段取词,如 ABCDEF => AB + ABCD + ABCDEF
- scws([3]) 表示采用指定参数为复合等级的 scws 分词,(若无特殊复合需求,无需指定)
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 不明确写明时候的默认值
tokenizer = default
cutlen 类型说明(搜索结果摘要截取长度)
默认值为 0 表示不截取。主要是针对某些内容特别长的字段在返回结果时自动剪取包含关键词的一小段文字。 典型的是 body 型字段默认为 300 。长度单位是字节,通常 UTF-8 编码的一个汉字为 3 个字节。
缩短匹配内容,可以减少网络传输内容,在请求量大的时候,能够极大减少网络IO消耗。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 不明确写明时候的默认值
cutlen = 0
weight 类型说明(混合区检索时的概率权重)
在混合检索(index=mixed)时,可以对标题和内容等不同字段进行权重计算,如果你不想该字段参与计算权重可设为 0 。 通常默认值为 1 ,但 title 型默认为 5 而 body 型则固定为 1 。
索引为混合(index=mixed/index=both)模式,表示即使不写明字段,也一定会在这些字段内检索数据,所以就会有我该优先匹配哪个字段的内容?的需求。比如,当搜关键词高考时候,一篇文章的标题,和另一篇文章的内容中均有涉及。因为 title 类型的的weight是5,body 类型是1,所以优先匹配 title,那么标题中有关键字的文章,会在匹配结果列表中更靠前。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
; 字段配置时,不写时候的默认值
weight = 1
phrase 类型说明( 是否支持精确检索)
即当给搜索语句加上引号时,则要求匹配的结果必须严格按照搜索词的顺序匹配,此外还支持用 NEAR 之类的语法来做精确检索(具体请查看官网)。通常默认值为 no,但是 title 和 body 型字段默认则为 yes 。值得注意的是该功能仅支持默认分词器,如非必要请勿开启此项, 因为这会增加索引数据的大小。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
phrase = no
non_bool 类型说明(强制指定是否为布尔索引)
布尔索引不参与权重排名计算,默认情况下所有自定义分词器的字段均为布尔索引。因此, 当您使用自定义分词器却又想让本字段参与权重计算的话,请将本项设为 yes。
以上是官网描述,举例说明下,如果你在字段[summary]使用了自定义分词器,而且想让自定义分词器指定的字段设置上权重,比如 summary 权重设置为 6,那么它比 title 的权重还高。当搜索一个关键词高考时候,在summary 中有高考一词的内容排名,会排在 title 中有高考的内容之前。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
[summary]
; 假设 custom 是我的自定义分词器(full/none/split 等系统提供的均为内置分词器)
tokennizer = custom
; 当设置自定分词器后,如果没有明确指明 non_bool ,则其值默认为 no。
; 想让summary影响匹配结果就要明确指定 non_bool = yes,然后指定权重值 weight = xx
non_bool = yes
实战讲解
比如我想自定一个搜索项目,用来搜索我站点文章数据。
xunsearch 的搜索项目中,字段名称可以跟 mysql 不一样,只要插入数据时候,设置好映射关系就可以。相当于就是一份数据,让两人来设计数据表,两个人设计的字段名很大可能不一样。但是只要保证我们从原始数据源读取数据后,往 xunsearch 的项目库中插入的时候,名字跟 xunsearch 的"表结构"一样就可以。
        
            
        
        
            
                ini
            
            
            
                
            
        
    
project.name = blog
project.default_charset = UTF-8
; 测试我就不写远程地址了
server.index = 8383
server.search = 8384
; 索引数据库中的唯一主键,这个只是用来区分数据,所以其他值保持默认就可以
[id]
type = id
[title]
; 表示这是内容的 title,一个项目中,最多只能有一个type = title
type = title
; 标题如果比较长,设置一下返回数据长度
cutlen = 300
[content]
; 主要内容,一个项目库只能有一个 type = body
type = body
; 内容一般都很长,必须设置返回数据的长度,否则会全部返回,浪费带宽
cutlen = 300
; 最后更新时间,我的库内都是毫秒时间戳,整形的
[update_time]
; 支持范围查询,需要索引配合,这是个固定筛选条件,所以索引用 self,必须明确指定字段才能检索
index = self
; 分词器,因为这个不是查数据用的,分词直接用全字匹配
tokenizer = full
; 为了支持时间范围查找,得设置为 numeric 类型
type = numeric
; 内容的概述部分
[summary]
; 索引设置为 both,既可以指定,也可以不指定,都会检索 summary。没有权重默认 weight = 1
index = both
; 控制客户端获取摘要的长度
cutlen = 300
; 来源ID,最后只是用来展示,所以不要要建立索引,也不会搜这个字段
[source_id]
; 内容类型 1图文 2视频 3音频 4图集,由于搜索结果要根据类型可以筛选,所以需要加索引
[type]
; 索引要明确指定,根据 type 类型检索时候才会走此索引
index = self
; 类型检索是要全字匹配的,不需要分词
tokenizer = full
以下是官网的搜索功能示例截图:

 
            