索引配置(一)加载配置文件以及服务端配置
对于一个搜索引擎来说,索引配置是非常重要,并且也是非常核心的内容。在 XS 中,我们的索引配置是通过一个配置文件来实现的。在前两篇文章的测试中,我们使用了一个叫做 demo 的索引配置。当时,我们直接就是写了一个 demo 这个名称,那么这个配置文件具体在哪里呢?
默认 DEMO
默认的 demo 索引的配置文件是 sdkpath/app/demo.ini
,由于我们是使用 Composer 安装的 SDK ,因此,它的路径就是在 vendor/hightman/xunsearch/app/demo.ini
。从 1.4.9 版本开始,大家可以自定义一个 XS_APP_ROOT
常量或者设置这个环境变量来指定默认项目配置目录。
如果我们不指定路径,只是给一个名称的话,XS 程序会自动到 SDK 的 app 目录下找对应名称的 .ini 文件。就像我们通过 PHP 代码实例化 XS
对象时,构造参数中也只写了一个 demo 一样。
$xs = new XS('demo');
现在我们就打开这个配置文件,看看里面有什么东西。
; vendor/hightman/xunsearch/app/demo.ini
project.name = demo
project.default_charset = utf-8
server.index = 8383
server.search = 8384
[pid]
type = id
[subject]
type = title
[message]
type = body
[chrono]
type = numeric
咱们一个一个来说。
- 分号
;
表示注释 project.name
表示项目或索引名称,这个在同一个 XS 应用实例中不能重复,也就是当前运行的这个 XS 服务里面叫 demo 的索引配置只能有一个,一般是和配置文件名称同名。project.default_charset
表示字符集,这个直接 utf-8 就好了。server.index
表示索引服务端配置,没有 ip 地址的表示当前本机,端口号是必须的。server.search
表示搜索服务端配置,没有 ip 地址的表示当前本机,端口号是必须的。[pid]
表示一个字段 Field ,就相当于是数据库中的字段名称。每个字段配置到下一个字段配置中间的部分为针对这个字段的相关配置。type
表示字段的类型,具体的类型有哪些我们后面再说。
这下明白为什么在第二篇文章中,我建立的 ES 索引为啥是这几个字段了吧,就是照搬的 XS 这个默认索引配置啦!
Server 配置
从这个配置的配置文件中可以看出,XS 的索引服务和搜索服务是分开的,所以它会占用两个端口。如果你是使用虚拟机搭建的,那么就需要给 server
相关的配置带上 IP 地址,比如:
server.index = 192.168.56.101:8383
server.search = 192.168.56.101:8384
注意,自 1.4.7
起,服务端地址可以使用 ;
分隔指定多个。 索引更新将同步到所有服务端,而搜索则随机从中挑选一个可用的服务端以达到均横效果。看出来是啥意思了没?直接通过配置文件,就可以实现负载均衡了,而且是多主同步。
server.index = 8383;192.168.56.101:8383
server.search = 8384;192.168.56.101:8384
这个配置就表示本机和 192.168.56.101 这台主机的 XS 实例都会同步建立索引,并且在搜索时会自动均衡查找。光说不练假把式,咱们就来试试。按照上面的配置修改 demo.ini 文件之后。直接测试搜索。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query demo 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 3 条数据中,大约有 2 条包含 项目 ,第 1-2 条,用时:0.0182 秒。
1. 关于 xunsearch 的 DEMO 项目测试 #1# [100%,0.44]
项目测试是一个很有意思的行为!
Chrono:1314336158
2. 项目测试第三篇 #3# [99%,0.44]
俗话说,无三不成礼,所以就有了第三篇
Chrono:1314336168
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query demo 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 0 条数据中,大约有 0 条包含 项目 ,第 0-0 条,用时:0.0569 秒。
第一次有数据是走得本机的 XS ,第二次没有数据,正是走了 192.168.56.101 这台虚拟机上的 XS 实例,之前我们并没有对这台机器上的 demo 添加数据,因此是查不到东西的。接下来我们再插入一条数据。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Indexer.php --source=csv demo
初始化数据源 ... csv
WARNING: input file not specified, read data from <STDIN>
开始批量导入数据 (请直接输入数据) ...
4,项目测试第四篇,两台同步写入试试,123123
INFO: reach end of file or error occured, total lines: 1
完成索引导入:成功 1 条,失败 0 条
刷新索引提交 ...
接着继续进行查询测试。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query demo 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 4 条数据中,大约有 3 条包含 项目 ,第 1-3 条,用时:0.0127 秒。
1. 项目测试第四篇 #4# [100%,0.33]
两台同步写入试试
Chrono:123123
2. 关于 xunsearch 的 DEMO 项目测试 #1# [98%,0.32]
项目测试是一个很有意思的行为!
Chrono:1314336158
3. 项目测试第三篇 #3# [98%,0.32]
俗话说,无三不成礼,所以就有了第三篇
Chrono:1314336168
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query demo 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 1 条数据中,大约有 1 条包含 项目 ,第 1-1 条,用时:0.0017 秒。
1. 项目测试第四篇 #4# [100%,0.26]
两台同步写入试试
Chrono:123123
大家多试几次,会发现它的负载均衡并不是轮询的。有兴趣的小伙伴可以看一下 vendor/hightman/xunsearch/lib/XS.class.php
中 getSearch()
方法的源码,它选取服务器连接的方式是随机的,随机返回一个服务端连接实例。也就是说,XS 在配置文件中实现的负载均衡并不是完全的均衡流量分配,也没有其它的配置,只有一个随机。
另外,如果其中一台机器挂掉了,也会将请求转发给其它服务器实例,比如我们关掉 192.168.56.101 这台主机。如果随机到这台主机,那么请求会卡顿一下,然后再次以本机连接返回成功查找到的数据。注意,XS 没有类似 Redis 的哨兵之类的机制,所以它应该是代码内部去实现的,当一个连接不可用之后就切换另一个连接,中间会有连接尝试和超时的时间。虽然不是那么强大,但是至少一套多副本高可用集群还是能够通过简单地配置文件来实现的。
在 PHP 代码中,通过 XSSearch 对象的一个方法,就可以获得当前查询使用的是哪个服务端连接。
<?php
require_once 'vendor/autoload.php';
$xs = new XS('demo');
print_r($xs->search->getConnString());
这里 XS 对象的 search 属性,直接就是一个 XSSearch 对象。第一篇文章时就已经说过,最终的查询方法 search()
方法,其实是 XSSearch 对应的方法。关于这些对象的内容,我们在后面会进行详细的学习。
默认值
如果我们不配置 server.index
或 server.search
,那么他们默认就会找本机的 8383 和 8384 端口,这个我们下面和其它内容一起再进行测试。
自定义配置文件
从开始到现在,我们一直看的,操作的,都是 XS 默认提供的那个索引配置文件,也就是 demo.ini ,接下来,咱们自己来定义一个自定义的。不过内容还是以 demo.ini 的为主。但是位置要换一下,比如说,放到当前运行目录的 config 目录下。
; ./config/demo2.ini
project.name = demo2
project.default_charset = utf-8
[pid]
type = id
[subject]
type = title
[message]
type = body
[chrono]
type = numeric
[author]
type = string
index = both
新建好这个 demo2.ini 文件,并且新增加了一个字段 author ,表示作者信息。另外在这个配置文件中,我们没有指定server.index
或 server.search
,这样它就会默认找本机的 8383 和 8384 端口。新增加的字段下面的参数先不用管,这些参数下篇文章再说。这回主要就是看看如何使用及加载我们自定义的索引文件。同样,还是使用 XS 自带的工具文件进行测试,其实只要将原来的 demo 换成绝对或相对路径的完整文件名就可以了。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Indexer.php --source=csv --clean ./config/demo2.ini
清空现有索引数据 ...
初始化数据源 ... csv
WARNING: input file not specified, read data from <STDIN>
开始批量导入数据 (请直接输入数据) ...
1,关于 xunsearch 的 DEMO 项目测试,项目测试是一个很有意思的行为!,1314336158
2,测试第二篇,这里是第二篇文章的内容,1314336160,zyblog
3,项目测试第三篇,俗话说,无三不成礼,所以就有了第三篇,1314336168,虎力大仙
INFO: reach end of file or error occured, total lines: 3
完成索引导入:成功 3 条,失败 0 条
刷新索引提交 ...
数据还是和原来一样。但是这里稍微有一点点改变,那就是第一条数据我们没有给 author 赋值。可以看到,不给参数赋值,也是可以插入成功的。然后还是进行搜索。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query ./config/demo2.ini 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 3 条数据中,大约有 2 条包含 项目 ,第 1-2 条,用时:0.0150 秒。
1. 关于 xunsearch 的 DEMO 项目测试 #1# [100%,0.44]
项目测试是一个很有意思的行为!
Chrono:1314336158 Author:
2. 项目测试第三篇 #3# [99%,0.44]
俗话说,无三不成礼,所以就有了第三篇
Chrono:1314336168 Author:虎力大仙
正常显示,但第一条数据中的 author 字段信息是空的。另外在你的 XS 服务端的数据目录里,会多出一个 demo2 的目录。如果是按我们第一篇文章中安装方式的话,虚拟机安装的会在 /usr/local/xunsearch/data
这个目录。 Docker 的话,则会在 /Users/zhangyue/XunSearch/data:/usr/local/xunsearch/data
挂载出来的 /Users/zhangyue/XunSearch/data
这个目录下看到相应的内容。
自定义的索引配置文件,如果不是放在 SDK 目录下的 app 文件夹中,就需要写完整的路径和文件名的,而如果你直接在 SDK 下的 app 中目录放置自己新增的配置文件,在加载的时候就可以不用指定路径以及那个 .ini 的后缀名,就和我们前面一直测试的 demo 一样。
多写少写字段以及字段类型不匹配测试
上面我们已经试过了少写了 author 字段的效果,下面我们再试试多写一些字段的效果。
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Indexer.php --source=csv ./config/demo2.ini
初始化数据源 ... csv
WARNING: input file not specified, read data from <STDIN>
开始批量导入数据 (请直接输入数据) ...
4,项目第四篇测试,多了个字段咋样,123123,zyblog,a,b,c
INFO: reach end of file or error occured, total lines: 1
完成索引导入:成功 1 条,失败 0 条
刷新索引提交 ...
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query ./config/demo2.ini 项目
--------------------
解析后的 QUERY 语句:Query(项目@1)
--------------------
在 4 条数据中,大约有 3 条包含 项目 ,第 1-3 条,用时:0.0145 秒。
1. 关于 xunsearch 的 DEMO 项目测试 #1# [100%,0.33]
项目测试是一个很有意思的行为!
Chrono:1314336158 Author:
2. 项目第四篇测试 #4# [99%,0.32]
多了个字段咋样
Chrono:123123 Author:zyblog
3. 项目测试第三篇 #3# [99%,0.32]
俗话说,无三不成礼,所以就有了第三篇
Chrono:1314336168 Author:虎力大仙
第四条测试数据后面我们多跟了一堆内容,很明显,这些内容不会进入到索引数据中。chrono 字段是一个 numeric ,从字面意思看,这是一个数字类型,如果我们给它字符串会怎么样呢?
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Indexer.php --source=csv ./config/demo2.ini
初始化数据源 ... csv
WARNING: input file not specified, read data from <STDIN>
开始批量导入数据 (请直接输入数据) ...
5,项目第五篇,字段类型不匹配,aabbcc,zyblog
INFO: reach end of file or error occured, total lines: 1
完成索引导入:成功 1 条,失败 0 条
刷新索引提交 ...
➜ source git:(master) ✗ php vendor/hightman/xunsearch/util/Quest.php --show-query ./config/demo2.ini zyblog
--------------------
解析后的 QUERY 语句:Query(Zzyblog@1)
--------------------
在 5 条数据中,大约有 3 条包含 zyblog ,第 1-3 条,用时:0.0139 秒。
1. 项目第五篇 #5# [100%,0.33]
字段类型不匹配
Chrono:0 Author:zyblog
2. 测试第二篇 #2# [97%,0.32]
这里是第二篇文章的内容
Chrono:1314336160 Author:zyblog
3. 项目第四篇测试 #4# [92%,0.30]
多了个字段咋样
Chrono:123123 Author:zyblog
看来 XS 在插入数据的时候,会对数据进行类型转换,字符串类型最终会变成 0 。
通过这些测试,大家可以发现,XS 对索引的兼容性还是比较好的。假如我们的系统中有多个索引配置,在操作的时候出现问题了,本来是要插入到 demo.ini 的数据被插入到了 demo2.ini 中,即使字段不对应也是可以插入成功的。有小伙伴会说了,这样的话如果数据插入错误了咱们也不知道呀。先提前说一嘴,type 类型为 id 的字段,是 XS 中必须的主键字段。如果你的系统中有多个索引配置,而且容易混乱的话,可以尝试将 id 类型的字段起不同的名字哦。这样的话,数据就插入不进去了,直接会报错。
PHP代码
使用 PHP 代码来指定索引文件也是一样的,直接就是 XS 对象在实例化时,给定相对或绝对路径的完整索引文件名。
$xs = new XS('./config/demo2.ini');
$doc = $xs->search->search("项目");
print_r($doc);
直接字符串定义配置文件
除了手动创建一个 .ini 文件之外,在 XS 中,还可以直接通过动态地字符串来创建索引。也就是说,我们可以将索引配置保存到数据库中,或者动态地配置索引内容。比如向下面这样。
$indexName = 'demo3';
$indexConfig = <<< EOF
project.name = $indexName
project.default_charset = utf-8
[pid]
type = id
[subject]
type = title
[message]
type = body
[chrono]
type = numeric
[author]
type = string
index = both
EOF;
这个索引配置是写在 PHP 代码中的,在这里就是动态地定义了一个索引名称。其它的内容都和 demo2.ini 是一样的。然后我们就通过 PHP 代码来插入数据。
$xs = new XS($indexConfig); // 使用上面的变量里定义的索引配置
if($argv[1]){ // 命令行运行时,有参数的时候才插入数据
// 清空索引
$xs->index->clean();
$data = [
[
'pid'=>1,
'subject'=>'三号DEMO的,关于 xunsearch 的 DEMO 项目测试',
'message'=>'项目测试是一个很有意思的行为!',
'chrono'=>1,
'author'=>'zyblog',
],[
'pid'=>2,
'subject'=>'三号DEMO的,测试第二篇',
'message'=>'这里是第二篇文章的内容',
'chrono'=>1314336160,
'author'=>'zyblog',
],[
'pid'=>3,
'subject'=>'三号DEMO的,项目测试第三篇',
'message'=>'俗话说,无三不成礼,所以就有了第三篇',
'chrono'=>123,
'author'=>'虎力大仙',
]
];
// 循环插入数据
foreach($data as $d){
$doc = new XSDocument;
$doc->setFields($d);
$xs->index->add($doc);
}
}
// 查询输出数据
$doc = $xs->search->search("");
print_r($doc);
注释已经写得很清楚了,同时我们也第一次看到了怎么在 PHP 代码进行数据的插入。现在可以直接运行这段代码。
➜ source git:(master) ✗ php 4.php 1
Array
(
)
参数随便写个 1 什么的就行,主要上的就是 $argv[1]
的判断条件能通过就行了,这样我们的代码就会走到插入数据中。最后打印出来的结果是空的数组,大家不要急,接下来我们去掉参数,并且稍等一会。
➜ source git:(master) ✗ php 4.php
Array
(
[0] => XSDocument Object
(
…………………………
是不是有数据啦,从这里可以看出,XS 之所以要分出 8383 和 8384 两个端口,分别用于索引和查询操作,就是因为它的索引操作是异步的。通过之前的学习,大家应该也了解到了搜索引擎需要对文档进行分词、保存等操作,而且还有一些其它的分析操作。这些操作都是比较耗时的,因此,会通过异步的方式进行索引的插入、修改、删除操作,在索引插入后,并不能马上展示出数据。因此,XS 是一个 近实时搜索引擎 ,包括 ES 也是这种搜索引擎,它的索引建立和数据插入会比 XS 快一些。近实时其实就是 接近 实时的意思,它们都会存在分词、解析的过程,即使是像 MySQL ,如果你的表中索引非常多,那么插入效率也一样会降低嘛。
幸好,对于日常中小型应用来说,这一块是可以不要求那么高的同步性的,而且它的速度也没有慢到忍受不了的程度。
在这个地方,还需要注意 search("")
这个方法,我们给的查询条件是一个空字符串,其实不用给参数也可以查出数据的,但是其中有个字段显示的结果会是有问题的,大家可以自己试试。我不知道原因,如果有了解的小伙伴可以评论留言哈。
总结
一开始正式的学,内容就有点多呀。其实还好啦,篇幅长主要还是贴的代码多,其实今天的主要内容就是标题上那两个,一个是关于索引配置文件的加载,自定义配置文件的加载,以及服务端的配置问题。在服务端的配置中,我们一上来就看到了如何通过索引配置文件来连接多台主机,这样就可以很方便地实现读写分离以及保证高可用。虽说它的功能没有 Redis 的哨兵那样简单方便,故障自动切换,但是咱们手动一下也不是啥大事啦,或者自己写心跳检测然后自动修改索引配置文件也是可以的啦。毕竟 Redis 不管是开发团队,还是社区资源以及活跃度,比 XS 可是高了不止一个数量级的。
好了,下篇文章我们将学习的就是索引配置中另一部分的重要内容,也就是每个字段下面的那些属性配置,就四个字:非常重要!
测试代码:
https://github.com/zhangyue0503/dev-blog/blob/master/xunsearch/source/4.php
参考文档:
http://www.xunsearch.com/doc/php/guide/ini.guide
【文章原创作者:阿里云代理 http://www.558idc.com/aliyun.html 复制请保留原URL】