taxusorg/xunsearch-laravel

XunSearch engine for laravel/scout.

v5.4.1 2023-09-02 13:27 UTC

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_TYPE_
索引类型 XUNSEARCH_INDEX_
分词器 XUNSEARCH_TOKENIZER_

设置的字段类型的具体效果,查看 XunSearch 官方文档

设置了分词器包含有参数时,通过设置 tokenizer_value 设置分词器参数。如果没有指定分词器,但设置了大于 0 的参数,则自动设置分词器为 XUNSEARCH_TOKENIZER_SCWS。都不设置则使用 XunSearch 默认分词器。

Model 的主键,例如 id,已被默认设为引擎的文档主键。 如果需要对 id 进行区间检索,把 id 的类型设为 self::XUNSEARCH_TYPE_NUMERIC。如果不需要对 id 进行检索,可以不添加 id 字段。

字段类型 self::XUNSEARCH_TYPE_TITLEself::XUNSEARCH_TYPE_BODY 只能分别设置一次。

检索

查询方法和 scout 相同。简单查询可以按照 laravel/scout 的官方文档 进行查询即可。

Model::search 方法返回 Builder 对象,在进行服务拓展时,已经对该对象注册了宏,可以获取到 XS 对象,自行调用查询功能。

已注册的宏

方法 描述
getXSTotal 获取该库中的总文档数
getXS 获取 Client 对象
getXSSearch 获取 XSSearch 对象
getXSIndex 获取 XSIndex 对象

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 对象的方法

方法 描述
getIds 获取检索结果的主键集合
getModels 获取检索模型结果的 Collection 集合
getLazyModels 获取检索模型结果的 LazyCollection 集合
query 替换检索结果转换模型查询闭包
getTotal 获取检索的总数
toArray 获取检索结果的 XSDocument 数组

检索结果转换模型查询闭包

通过 Results 中的 getModelsgetLazyModels 方法,把搜索结果转换成 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();

除了 titlebody 特殊字段, XunSearch 默认设定字段为 string,需要进行区间检索的字段,要设为 numeric 或者 date 才能正常检索。

Builder 拓展的方法

方法 描述
setFuzzy 开启模糊搜索
setCutOff 设置”百分比“和”权重“剔除参数
setRequireMatchedTerm 是否在搜索结果文档中返回匹配词表
setWeightingScheme 设置检索匹配的权重方案
setAutoSynonyms 开启自动同义词搜索功能
setSynonymScale 设置同义词搜索的权重比例
setSort 设置多字段组合排序方式。该方法会覆盖 orderBy 方法。若无必要使用 orderBy 就行
setDocOrder 设置结果按索引入库先后排序
setCollapse 设置折叠搜索结果
addRange 添加搜索过滤区间或范围
addWeight 添加权重索引词
setScwsMulti 设置当前搜索语句的分词复合等级

XunSearchTrait 中包含一些静态方法,可以获取 Client 对象等。

方法 描述
XS 获取 Client 对象
XSSearch 获取 XSSearch 对象
XSIndex 获取 XSIndex 对象
XSTotal 获取该库中的总文档数
search 返回 Builder 对象
XSAllSynonyms 获取当前库内的全部同义词列表
XSSynonyms 获取指定词汇的同义词列表
XSHotQuery 获取热门搜索词列表
XSRelatedQuery 获取相关搜索词列表
XSExpandedQuery 获取展开的搜索词列表
XSCorrectedQuery 获取修正后的搜索词列表

注意: 通过静态方法获取 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 方法。

相关链接

laravel/scout

laravel/scout 文档

hightman/xs-sdk-php

XunSearch 文档