tomtruyen/fuzzyness

一个基于 tomtruyen/Fuzzyness 的提供伪模糊搜索的 Laravel 数据库查询的包。

1.0.7 2022-06-02 13:12 UTC

This package is auto-updated.

Last update: 2024-09-30 01:41:54 UTC


README

Code example

License

Fuzzyness

本包基于 mattkingshott 的 "Quest"。

有何不同?

  • Fuzzyness 不会跟踪所有 "whereFuzzy" 调用的总 "模糊得分"。
    • 原因:不跟踪总模糊得分可以大大加快在拥有 100k+ 条记录的数据库中的查询速度。缺点是内置的按总模糊得分排序功能不存在。
  • 可添加自定义匹配器列表
  • 可选使用预设匹配器的完整列表或精简版本

关于包

此包可以启用 Laravel 数据库和 Eloquent 查询中的伪模糊搜索。由于其模式匹配方法,它仅支持 MySQLMariaDB,尽管我也欢迎任何支持类似 Postgres 数据库的 PR。

此库的大部分内容基于 Tom Lingham 为现在已废弃的 Laravel Searchy 包所做的出色工作。如果您想了解模糊搜索的工作原理的背景,请查看该项目的说明。

安装

使用 composer 拉取包

composer require tomtruyen/Fuzzyness

用法

Fuzzyness 自动注册一个包含多个宏的服务提供者。然后,这些宏附加到底层的 Illuminate\Database\Query\Builder 类。

过滤结果

您可以通过调用 whereFuzzy 方法执行模糊搜索。此方法接受三个参数。第一个是字段名称,第二个是用于搜索的值,例如,第三个是 "extended"(默认:false)。Extended 使用所有预构建的匹配器,但比非扩展版本慢,但为了获得更具体或更准确的结果,建议将其设置为 true

DB::table('users')
  ->whereFuzzy('name', 'jd', false) // matches John Doe
  ->first();

User::whereFuzzy('name', 'jd', false) // matches John Doe
    ->first();

您也可以通过链式调用多个 whereFuzzy 方法调用在多个列上执行模糊搜索

User::whereFuzzy('name', 'jd', false)  // matches John Doe
    ->whereFuzzy('email', 'gm', false) // matches @gmail.com
    ->first();

您还可以选择传递自己的 "Matchers" 列表,如果您想使用自定义匹配器或自定义现有匹配器的列表。

注意:您还必须传递当字段与匹配器匹配时的得分

DB::table('users')
  ->whereCustomFuzzy('name', 'jd', [StartOfWordsMatcher::class => 35]) // matches John Doe
  ->first();

User::whereCustomFuzzy('name', 'jd', [StartOfWordsMatcher::class => 35]) // matches John Doe
    ->first();

预设匹配器及其得分的列表

array $matchers = [
    ExactMatcher::class                 => 100,
    StartOfStringMatcher::class         => 50,
    AcronymMatcher::class               => 42,
    ConsecutiveCharactersMatcher::class => 40,
    StartOfWordsMatcher::class          => 35,
    StudlyCaseMatcher::class            => 32,
    InStringMatcher::class              => 30,
    TimesInStringMatcher::class         => 8,
];

排序结果

当使用 Fuzzyness 时,将在您的搜索结果中包含一个 'relevance_*' 列。这里的 * 是通配符,将被替换为您正在搜索的字段名称,例如。

User::whereFuzzy('email', 'gm') // relevance_email

此列包含记录在应用每个模糊搜索模式匹配器后收到的得分。得分越高,记录与搜索词的匹配度越高。

当然,您会希望按得分排序结果,以便得分最高的记录首先出现。为了简化这个过程,Fuzzyness 包含一个 orderByFuzzy 辅助方法,该方法包装相关的 orderBy 子句

User::whereFuzzy('name', 'jd')
    ->orderByFuzzy('name')
    ->first();

// Equivalent to:

User::whereFuzzy('name', 'jd')
    ->orderBy('relevance_name', 'desc')
    ->first();

如果您正在跨多个字段进行搜索,可以向 orderByFuzzy 方法提供一个 array

User::whereFuzzy('name', 'jd')
    ->whereFuzzy('email', 'gm')
    ->orderByFuzzy(['name', 'email'])
    ->first();

// Equivalent to:

User::whereFuzzy('name', 'jd')
    ->orderBy('relevance_name', 'desc')
    ->orderBy('relevance_email', 'desc')
    ->first();

限制

无法使用paginate方法,因为模糊搜索时,相关性字段被省略了。Laravel在获取需要用于LengthAwarePaginator的记录数时,会执行一个二级查询,而这些字段没有被包含在内。然而,您可以无障碍地使用simplePaginate方法,或者结合使用skiptake。在很多情况下,这仍然是一个更好的选择,尤其是在处理大量数据集时,因为当翻页数过多时,paginate方法会变得很慢。

贡献

感谢您考虑为Fuzzyness做出贡献。您欢迎提交包含改进的PR,但如果这些改进是实质性的,请确保也包含相应的测试或测试。

支持项目

如果您想支持Fuzzyness的开发,请考虑赞助我。非常感谢!

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件