blessingk / searchy
Laravel Searchy使通过模糊搜索、基本字符串匹配、Levenshtein距离等功能进行用户驱动搜索变得简单。
Requires
- php: ^5.5.9 || ^7.0 || ^8.1
- illuminate/support: ^5.1 || ^6.0 || ^7.0 || ^10.0
Requires (Dev)
- graham-campbell/testbench: ^3.4 || ^4.0 || ^5.0
- phpunit/phpunit: ^4.8 || ^5.7 || ^6.3 || ^7.0 || ^8.5 || ^10.0
This package is not auto-updated.
Last update: 2024-09-28 04:22:24 UTC
README
数据库搜索变得简单
Searchy是一个易于使用、轻量级的、仅支持MySQL的Laravel包,它使得在模型中运行用户驱动搜索变得简单而有效。它使用伪模糊搜索和其他加权机制,具体取决于您启用的搜索驱动程序。它不需要在您的服务器上安装其他软件(因此可能比专用搜索程序稍慢),但可以在几分钟内设置并就绪。
安装
在终端中运行composer require blessingk/searchy
以将包拉入您的vendor文件夹。
将服务提供者添加到Laravel的./config/app.php
文件中的providers
数组中
BlessingK\Searchy\SearchyServiceProvider::class
如果您想快速访问它,请在Laravel的./config/app.php
文件中的aliases
数组中添加别名
'Searchy' => BlessingK\Searchy\Facades\Searchy::class
用法
要使用Searchy,您可以利用魔术方法。
例如,如果您正在搜索users
表中的用户名称和电子邮件列/字段,您将运行
$users = Searchy::users('name', 'email')->query('John Smith')->get();
您也可以写成这样
$users = Searchy::search('users')->fields('name', 'email')->query('John Smith')->get();
在这种情况下,将您想要搜索的列传递给fields()
方法。
这两个示例都返回包含您的搜索结果的对象数组。如果您想对结果进行进一步操作,可以使用getQuery()
而不是get()
来返回数据库查询对象实例。
$users = Searchy::search('users')->fields('name', 'email')->query('John Smith') ->getQuery()->having('relevance', '>', 20)->get();
返回结果的数量限制
要限制您的结果,您可以使用Laravel内置的Database Query Builder方法并链接其他方法来缩小结果。
// Only get the top 10 results $users = Searchy::search('users')->fields('name', 'email')->query('John Smith') ->getQuery()->limit(10)->get();
搜索多个列
您还可以将多个参数添加到要搜索的列/字段列表中。
例如,如果您想搜索用户的名称、电子邮件地址和用户名,您可能运行
$users = Searchy::users('name', 'email', 'username')->query('John Smith')->get();
如果您需要动态构建表格列表,您也可以将字段数组作为第一个参数传递(所有其他后续参数将被忽略)
$users = Searchy::users(['name', 'email', 'username'])->query('John Smith')->get();
搜索连接/连接的列
有时您可能希望利用对连接列的搜索。例如,在一个包含first_name
和last_name
字段的表上,但您只想运行一个查询。为此,可以使用双冒号分隔列
$users = Searchy::users('first_name::last_name')->query('John Smith')->get();
软删除的记录
默认情况下,软删除将不包括在您的结果中。但是,如果您希望包含软删除的记录,您可以在指定表和字段后添加withTrashed()
;
Searchy::users('name')->withTrashed()->query('Batman')->get();
仅返回特定列
您可以在搜索中指定要返回的列
$users = Searchy::users('first_name::last_name')->query('John Smith')->select('first_name')->get(); // Or you can swap those around... $users = Searchy::users('first_name::last_name')->select('first_name')->query('John Smith')->get();
但是,这将返回relevance
别名的列,而不管在此处输入了什么。
如何获取Laravel Eloquent集合
将搜索结果转换为Laravel Eloquent模型集合超出了此项目的范围。但是,一种简单的方法是在不必要地击中数据库的情况下实现这一点,即使用Eloquent的hydrate()
方法。
\App\User::hydrate(Searchy::users('name', 'email')->query('Andrew')->get());
此方法从纯数组创建模型集合。这正好符合我们的情况,因为Searchy的结果以数组的形式提供,并且使用hydrate
,我们将它们转换为User
模型的实例。
支持Unicode字符
如果您在搜索数据中遇到Unicode字符导致返回结果有问题,您可以使用FuzzySearchUnicodeDriver
。
请注意:在将字符串插入到原始MySQL语句之前,通过 FuzzySearchUnicodeDriver
传递的字符串没有经过消毒处理。您必须首先自行消毒字符串,否则可能会使您的应用程序面临SQL注入攻击。已提醒您。
使用方法:首先按照说明发布您的配置文件(php artisan vendor:publish
),并将默认驱动从 fuzzy
更改为 ufuzzy
。
return [ 'default' => 'ufuzzy', ... ]
配置
您可以将配置文件发布到 app
目录,并通过运行 php artisan vendor:publish
覆盖设置,将配置复制到您的配置文件夹作为 searchy.php
。
您可以在配置文件中设置用于搜索的默认驱动。目前您的选项有:fuzzy
、simple
和 levenshtein
。
当运行搜索时,您也可以使用以下语法覆盖这些方法
Searchy::driver('fuzzy')->users('name')->query('Batman')->get();
驱动程序
Searchy利用“驱动程序”来处理您指定的字段的各种匹配条件。
驱动程序只是由一组指定的“匹配器”组成的,这些匹配器基于特定条件匹配字符串。
目前只有三个驱动程序:Simple、Fuzzy和Levenshtein(实验性)。
简单搜索驱动程序
简单搜索驱动程序仅使用3个匹配器,每个匹配器都使用最适合我的测试环境的相应乘数。
protected $matchers = [ 'BlessingK\Searchy\Matchers\ExactMatcher' => 100, 'BlessingK\Searchy\Matchers\StartOfStringMatcher' => 50, 'BlessingK\Searchy\Matchers\InStringMatcher' => 30, ];
模糊搜索驱动程序
模糊搜索驱动程序是一组设置为以下方式的匹配器。乘数是我使用的,但您可以随意更改这些或创建具有相同匹配器的自定义驱动程序,并更改乘数以适应。
protected $matchers = [ 'BlessingK\Searchy\Matchers\ExactMatcher' => 100, 'BlessingK\Searchy\Matchers\StartOfStringMatcher' => 50, 'BlessingK\Searchy\Matchers\AcronymMatcher' => 42, 'BlessingK\Searchy\Matchers\ConsecutiveCharactersMatcher' => 40, 'BlessingK\Searchy\Matchers\StartOfWordsMatcher' => 35, 'BlessingK\Searchy\Matchers\StudlyCaseMatcher' => 32, 'BlessingK\Searchy\Matchers\InStringMatcher' => 30, 'BlessingK\Searchy\Matchers\TimesInStringMatcher' => 8, ];
Levenshtein搜索驱动程序(实验性)
Levenshtein搜索驱动程序使用Levenshtein距离来计算字符串之间的“距离”。它要求您在MySQL中有一个类似于以下存储过程的存储过程:levenshtein(string1, string2)
。在 res
文件夹中有一个包含合适函数的SQL文件 - 欢迎使用此文件。
protected $matchers = [ 'BlessingK\Searchy\Matchers\LevenshteinMatcher' => 100 ];
匹配器
ExactMatcher
匹配精确字符串并应用高乘数以将任何精确匹配项置于顶部。
StartOfStringMatcher
匹配以搜索字符串开头的字符串。例如,搜索“hel”会匹配“Hello World”或“helping hand”。
AcronymMatcher
匹配类似首字母缩略词的字符串,但不返回Studly Case匹配。例如,搜索“fb”会匹配“foo bar”或“Fred Brown”,但不匹配“FreeBeer”。
ConsecutiveCharactersMatcher
匹配包含字符串中所有字符的字符串,这些字符在字符串中的位置相对。它还计算字符串中匹配字符的百分比,并相应地应用乘数。
例如,搜索“fba”会匹配“Foo Bar”或“Afraid of bats”,但不匹配“fabulous”。
StartOfWordsMatcher
匹配搜索中每个单词的起始单词与单词中的每个单词。
例如,搜索“jo ta”会匹配“John Taylor”或“Joshua B. Takeshi”。
StudlyCaseMatcher
仅使用单词的首字母匹配Studly Case字符串。
例如,搜索“hp”会匹配“HtmlServiceProvider”或“HashParser”,但不匹配“hasProvider”。
InStringMatcher
匹配字符串中任何位置的字符串,且不区分大小写。
例如,搜索“smi”会匹配“John Smith”或“Smiley Face”。
TimesInStringMatcher
根据搜索字符串在字符串中出现的次数匹配字符串,然后为每个出现应用乘数。例如,搜索“tha”会匹配“I hope that that cat has caught that mouse”(3 x 乘数)或“Thanks, it was great!”(1 x 乘数)。
LevenshteinMatcher
参见 Levenshtein驱动程序
扩展
驱动程序
创建自定义搜索驱动器非常简单。只需创建一个继承自 BlessingK\Searchy\SearchDrivers\BaseSearchDriver
的类,并添加一个名为 $matchers
的属性,该属性是一个数组,其中包含匹配器类的名称作为键,每个匹配器的乘数作为值。您可以从中选择 Searchy 已经包含的类,或者创建您自己的类。
匹配器
要创建自己的匹配器,您可以创建一个继承自 BlessingK\Searchy\Matchers\BaseMatcher
的类,并且(对于简单的匹配器)重写 formatQuery
方法,以便返回一个在所需位置带有 %
通配符的字符串。对于更高级的扩展,您可能还需要重写 buildQuery
方法和其他方法。
贡献代码 & 报告错误
如果您想改进这里的代码,请随时提交一个 pull request。
如果您发现任何错误,请在此提交,我会尽快回复。请确保提供尽可能多的信息。