baril / sqlout
Laravel Scout 的 MySQL 全文搜索驱动。
Requires
- php: ^7.3|^8.0
- illuminate/database: ^8.79|^9.46|^10.0
- illuminate/support: ^8.79|^9.46|^10.0
- laravel/scout: ^9.0|^10.0
Requires (Dev)
- orchestra/testbench: ^6.23|^7.0|^8.0
- phpcsstandards/php_codesniffer: ^3.7
- wamania/php-stemmer: ^3.0
Suggests
- baril/smoothie: Some fruity additions to Laravel's Eloquent.
- wamania/php-stemmer: PHP stemmer that can be used together with Sqlout.
README
Sqlout 是一个针对 Laravel Scout 的非常简单的 MySQL 驱动。它将数据索引到 MySQL 数据库的专用表中,并使用全文索引进行搜索。它适用于小型项目,对于需要更大解决方案(如 ElasticSearch)的项目来说可能过于冗余。
Sqlout 与 Scout 9 的原生 Database
引擎不同,因为它将数据索引到单独的专用表中,并使用全文索引。Sqlout 还具有更多功能,例如字段权重和词干提取。
Sqlout 与 Laravel 5.8+ 到 10.x 和 Scout 7.1+ / 8.x / 9.x / 10.x 兼容(感谢 ikari7789 为 Laravel 9 和 10 / Scout 9 和 10 提供支持)。
版本兼容性
设置
需要此包
composer require baril/sqlout
发布配置
php artisan vendor:publish
如果您不使用包发现,请手动将服务提供者(Scout 和 Sqlout 的)添加到您的 config/app.php
文件中
return [ // ... 'providers' => [ // ... Laravel\Scout\ScoutServiceProvider::class, Baril\Sqlout\SqloutServiceProvider::class, ], ];
迁移您的数据库
php artisan sqlout:make-migration
php artisan migrate
这将创建一个名为 searchindex
的表(表名可以在配置文件中自定义)。
如果您想索引属于不同连接的模型,您需要在每个连接上创建一个 Sqlout 表。要创建非默认连接上的表,您可以调用 sqlout:make-migration
命令并传递连接名
php artisan sqlout:make-migration my_other_connection
php artisan migrate
使模型可搜索
use Baril\Sqlout\Searchable; class Post extends Model { use Searchable; protected $weights = [ 'title' => 4, 'excerpt' => 2, ]; public function toSearchableArray() { return [ 'title' => $this->post_title, 'excerpt' => $this->post_excerpt, 'body' => $this->post_content, ]; } }
上面的示例类似于在 Scout 文档 中描述的内容,但有以下差异/添加内容
- 您会注意到该模型使用的是
Baril\Sqlout\Searchable
特性,而不是Laravel\Scout\Searchable
。 - 可以使用
$weight
属性来“增强”某些字段。默认值是 1。
完成这些后,您可以使用 Scout 的 Artisan 命令索引您的数据
php artisan scout:import "App\Post"
您的模型在保存时也会自动索引。
搜索
基础
$results = Post::search('this rug really tied the room together')->get(); $results = Post::search('the dude abides')->withTrashed()->get();
有关更多详细信息,请参阅 Scout 文档。
Sqlout 的构建器还提供了以下附加方法
// Restrict the search to some fields only: $builder->only('title'); $builder->only(['title', 'excerpt']); // (use the same names as in the toSearchableArray method) // Retrieve the total number of results: $nbHits = $builder->count();
使用作用域
使用 Sqlout,您还可以在搜索构建器上使用您的模型作用域,就像它在模型本身上的查询构建器一样。同样,所有对搜索构建器上的 where
方法的调用都将转发到模型的查询构建器。
$results = Post::search('you see what happens larry') ->published() // the `published` scope is defined in the Post class ->where('date', '>', '2010-10-10') ->get();
⚠️ 请记住,这些转发的范围实际上将应用于子查询(主查询是
searchindex
表上的查询)。这意味着例如添加order by
子句的范围没有任何效果。有关正确排序结果的方法,请参阅下面。
如果您的范围名称与 Baril\Sqlout\Builder
对象的方法名称冲突,您可以将您的范围包装在 scope
方法中
$results = Post::search('ve vant ze money lebowski') ->scope(function ($query) { $query->within('something'); }) ->get();
搜索模式
MySQL 的全文搜索有 3 种口味
- 自然语言模式,
- 带有查询扩展的自然语言模式,
- 布尔模式。
Sqlout 的默认模式是“自然语言”(但可以在配置文件中更改)。
您还可以通过以下方法在每个查询的基础上在所有 3 种模式之间进行切换
$builder->inNaturalLanguageMode(); $builder->withQueryExpansion(); $builder->inBooleanMode();
排序结果
如果没有指定排序,结果将按得分排序(最相关优先)。但您也可以按表格中的任何列排序结果。
$builder->orderBy('post_status', 'asc')->orderByScore(); // "post_status" is a column of the original table
在下面的示例中,结果将首先按状态排序,然后按得分降序排列。
过滤器、分词器、停用词和词干提取
在您的配置文件中,您可以自定义索引内容和搜索词的处理方式
return [ // ... 'sqlout' => [ // ... 'filters' => [ // anything callable (function name, closure...) 'strip_tags', 'html_entity_decode', 'mb_strtolower', 'strip_punctuation', // this helper is provided by Sqlout (see helpers.php) ], 'token_delimiter' => '/[\s]+/', 'minimum_length' => 2, 'stopwords' => [ 'est', 'les', ], 'stemmer' => Wamania\Snowball\Stemmer\French::class, ], ];
在示例中,词干提取器来自包 wamania/php-stemmer
,但任何具有 stem
方法的类,或者任何可调用的东西,例如闭包,都可以。