taxusorg / xunsearch-laravel
XunSearch engine for 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
方法。