taxusorg / xunsearch-laravel
XunSearch 引擎适用于 laravel/scout。
Requires
- php: ^7.1|^8.0
- hightman/xunsearch: ^1.4
- laravel/scout: ^6.1|^7.0|^8.0|^9.0|^10.0
Requires (Dev)
- laravel/framework: *
- phpunit/phpunit: ^9.0
README
介绍
此包扩展了 laravel/scout 服务,以使用 XunSearch 搜索 功能。
有关 XunSearch 的安装,请参阅 XunSearch 的官方文档。
有关 laravel/scout 的安装和使用,请参阅 laravel/scout 的官方文档。
项目地址
当 github 不稳定时,可以上 gitee 替代。有问题可以创建 issues 反馈
安装
使用 composer
composer require taxusorg/xunsearch-laravel
将配置文件复制到配置目录,配置文件内容不多,而且可以在 .env 文件中设置。手动复制或使用命令复制:
php artisan vendor:publish --provider="Taxusorg\XunSearchLaravel\XunSearchServiceProvider"
修改 scout 配置文件 config/scout.php,让 scout 使用 XunSearch 引擎
'driver' => env('SCOUT_DRIVER', 'xunsearch'),
或者直接在 .env 文件中设置
SCOUT_DRIVER=xunsearch
修改 XunSearch 配置文件 config/xunsearch.php
'server_host' => env('XUNSEARCH_SERVER_HOST', '127.0.0.1'), 'server_index_host' => env('XUNSEARCH_SERVER_INDEX_HOST', null), 'server_index_port' => env('XUNSEARCH_SERVER_INDEX_PORT', '8383'), 'server_search_host' => env('XUNSEARCH_SERVER_SEARCH_HOST', null), 'server_search_port' => env('XUNSEARCH_SERVER_SEARCH_PORT', '8384'), 'default_charset' => env('XUNSEARCH_DEFAULT_CHARSET', 'utf-8'),
或者直接在 .env 文件中设置需要修改的内容,没有特殊情况默认即可
XUNSEARCH_SERVER_HOST=127.0.0.1
使用
在 Model 中使用搜索功能,先引入 Searchable Trait,详见 Scout 使用文档。
use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Blog extends Model { use Searchable;
要使用 XunSearch,Model 还需要实现指定接口。实现接口需要添加 xunSearchFieldsType 方法进行字段类型设置
use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; use Taxusorg\XunSearchLaravel\XunSearchModelInterface; class Blog extends Model implements XunSearchModelInterface { use Searchable; public function xunSearchFieldsType() { return [ 'id' => [ 'type'=>self::XUNSEARCH_TYPE_NUMERIC, ], 'title' => [ 'type'=>self::XUNSEARCH_TYPE_TITLE, ], 'body' => [ 'type'=>self::XUNSEARCH_TYPE_BODY, ], 'field' => [ 'tokenizer'=>self::XUNSEARCH_TOKENIZER_XLEN, 'tokenizer_value'=>2, ], 'created_at' => [ 'type'=>self::XUNSEARCH_TYPE_DATE, 'index'=>self::XUNSEARCH_INDEX_NONE, ], ]; } }
每个字段可以设置 字段类型、索引类型和分词器。设置关键词已经在接口中定义常量,前缀分别为:
查看 XunSearch 官方文档 以了解设置的字段类型的具体效果。
设置了分词器包含有参数时,通过设置 tokenizer_value 设置分词器参数。如果没有指定分词器,但设置了大于 0 的参数,则自动设置分词器为 XUNSEARCH_TOKENIZER_SCWS。都不设置则使用 XunSearch 默认分词器。
Model 的主键,例如 id,已被默认设为引擎的文档主键。 如果需要对 id 进行区间检索,把 id 的类型设为 self::XUNSEARCH_TYPE_NUMERIC。如果不需要对 id 进行检索,可以不添加 id 字段。
字段类型 self::XUNSEARCH_TYPE_TITLE 和 self::XUNSEARCH_TYPE_BODY 只能分别设置一次。
检索
查询方法和 scout 相同。简单查询可以按照 laravel/scout 的官方文档 进行查询即可。
Model::search 方法返回 Builder 对象,在进行服务拓展时,已经对该对象注册了宏,可以获取到 XS 对象,自行调用查询功能。
已注册的宏
Client 对象是对 XS 对象的包装,包含 XS 对象的属性和行为,可以当作 XS 对象使用。
注意: 通过 Builder 获取的 Client 对象是和 Builder 一对一绑定的。 如果 Client 没有被另外引用,当 Builder 被释放时 Client 和其中的 XS 对象也被释放。 如果同时存在多个 Builder,对分别获取的 Client 和 XS 对象的设置互不干扰。
例
$builder = Blog::search(); $builder->getXSSearch()->addRange('id', 1, 50); $blogs = $builder->get();
检索结果
检索时使用 get 方法返回 Model 对象的集合,scout 已经对检索结果转换成 Model,而 raw 方法返回的是原始数据,为了灵活和方便,原始数据返回的是 Results 对象。
Results 对象是可遍历对象,遍历的内容为 XSDocument 对象。
$results = Blog::search('test')->raw(); foreach ($results as $document) { // XSDocument $document }
同时,Results 对象可以调用 getModels 方法获取和 Builder::get 方法相同的内容。
$blogs = Blog::search('test')->get(); //------ $results = Blog::search('test')->raw(); $blogs = $results->getModels();
Results 对象的方法
检索结果转换模型查询闭包
通过 Results 中的 getModels 或 getLazyModels 方法,把搜索结果转换成 Model 集合时,可以传入闭包函数,对转换过程的查询进行控制。该闭包是一次性生效的。
$results = Blog::search('word')->raw(); $blogs = $results->getModels(function ($query) { /** @var \Illuminate\Database\Eloquent\Builder $query */ // $query->where(); // 添加查询条件 }); // 再次转换不添加查询条件 $blogs = $results->getModels();
传入 getModels 闭包类似于在查询过程中 query 方法指定查询闭包。但是,在 query 传入的闭包不是一次性生效的。而且,该闭包会临时被 getModels 方法传入的闭包替换。
$callback = function ($query) { /** @var \Illuminate\Database\Eloquent\Builder $query */ // $query->where(); // 添加查询条件 } $blogs = Blog::search('word')->query($callback)->get(); $result = Blog::search('word')->query($callback)->raw(); $blogs = $result->getModels(); // 以上都会调用 $callback。下边的形式 $callback 被临时覆盖,只调用后边传入的闭包。 $blogs = $result->getModels(function ($query) { // $query->where(); // 添加查询条件 });
如果需要在 Results 对象中永久替换查询闭包函数,使用 query 方法传入闭包。
$callback = function ($query) { // $query->where(); // 添加查询条件 } $result = Blog::search('word')->query($callback)->raw(); // 传入闭包进行替换,且永久生效 $blogs = $result->query(function ($query) { // $query->where(); // 添加查询条件 })->getModels();
拓展查询
Model 可以引入 XunSearchTrait 增加查询方法。XunSearchTrait 中已经引入了 Searchable 且重写了 search 方法,所以不必同时引入 Searchable。
use Illuminate\Database\Eloquent\Model; use Taxusorg\XunSearchLaravel\XunSearchModelInterface; use Taxusorg\XunSearchLaravel\XunSearchTrait; class Blog extends Model implements XunSearchModelInterface { use XunSearchTrait; public function xunSearchFieldsType() { // ... } }
在使用 XunSearchTrait 之后,search 返回的是拓展之后的 Builder,可以使用 range 等方法。 例如设定 id 字段为 self::XUNSEARCH_TYPE_NUMERIC,在 id 大于 20 小于等于 60 的范围内搜索 word
Blog::search('word')->addRange('id', 20, 60)->get();
除了 title 和 body 特殊字段, XunSearch 默认设定字段为 string,需要进行区间检索的字段,要设为 numeric 或者 date 才能正常检索。
Builder 拓展的方法
XunSearchTrait 中包含一些静态方法,可以获取 Client 对象等。
注意: 通过静态方法获取 Client 对象时,同等于通过 search 方法获取 Builder 对象,再通过 Builder::getXS 获取 Client。 获取到 Client 后,Builder 对象已经被丢弃。所以该 Client 不属于任何 Builder。 可以通过该方法获取 XS 对象进行与 Model、Scout 等无关的原始操作。
更新
5.0.x
- 支持 Scout:10.*
4.3.x
- 重命名 XunSearchTrait 静态方法
4.2.x
- Results 实现Arrayable接口,方法getArray改为toArray
4.1.x
- 支持Scout:9.*
4.0.x
- raw方法返回Results对象
- 扩展Builder
- 重写search方法,引入
XunSearchTrait时不必引入Searchable - 增加Client类,包装XS对象。当Client被解构时解构XS对象
3.0.x
- 修改接口名称和路径
- 每个builder对应一个XS对象,可以通过Trait添加的方法获取或调用XS对象的方法
2.1.x
XunSearchTrait中移除cleanSearchable方法,请使用Scout中的removeAllFromSearch方法。