PHP 的模糊搜索库
这是很棒的 Fuse.js 项目的 PHP 端口,旨在尽可能提供完整的 API 兼容性。
查看他们的演示和示例,以充分了解该库的功能。
最新兼容的 Fuse.js 版本:7.0.0
目录:
该软件包可通过 Composer 获得。要将其添加到您的项目中,只需运行:
composer require loilo/fuse
请注意,使用 Fuse 至少需要 PHP 7.4。
这是一个简单的用法示例:
<?php
require_once ' vendor/autoload.php ' ;
$ list = [
[
' title ' => " Old Man's War " ,
' author ' => ' John Scalzi ' ,
],
[
' title ' => ' The Lock Artist ' ,
' author ' => ' Steve Hamilton ' ,
],
[
' title ' => ' HTML5 ' ,
' author ' => ' Remy Sharp ' ,
],
[
' title ' => ' Right Ho Jeeves ' ,
' author ' => ' P.D Woodhouse ' ,
],
];
$ options = [
' keys ' => [ ' title ' , ' author ' ],
];
$ fuse = new Fuse Fuse ( $ list , $ options );
$ fuse -> search ( ' hamil ' );
这会产生以下结果(其中每个结果的item
引用匹配的条目本身,并且refIndex
提供该项目在原始$list
中的位置):
[
[
' item ' => [
' title ' => ' The Lock Artist ' ,
' author ' => ' Steve Hamilton ' ,
],
' refIndex ' => 1 ,
],
[
' item ' => [
' title ' => ' HTML5 ' ,
' author ' => ' Remy Sharp ' ,
],
' refIndex ' => 2 ,
],
];
Fuse 有很多选项可以优化您的搜索:
isCaseSensitive
bool
false
指示比较是否应区分大小写。
includeScore
bool
false
分数是否应包含在结果集中。 0
分表示完全匹配, 1
分表示完全不匹配。
includeMatches
bool
false
匹配项是否应包含在结果集中。当true
时,结果集中的每条记录将包含匹配字符的索引。因此,这些可以用于突出显示的目的。
minMatchCharLength
int
1
仅返回长度超过该值的匹配项。 (例如,如果您想忽略结果中的单个字符匹配,请将其设置为2
)。
shouldSort
bool
true
是否按分数对结果列表进行排序。
findAllMatches
bool
false
当为 true 时,匹配函数将继续到搜索模式的末尾,即使已在字符串中找到完美匹配。
keys
array
[]
将搜索的键列表。这支持嵌套路径、加权搜索、字符串和对象数组中的搜索。
location
int
0
确定预期在文本中找到的模式的大概位置。
threshold
float
0.6
匹配算法在什么时候放弃。阈值0.0
需要完美匹配(字母和位置),阈值1.0
可以匹配任何内容。
distance
int
100
确定匹配与模糊位置(由location
指定)的接近程度。与模糊位置distance
字符较远的精确字母匹配将被评分为完全不匹配。 distance
0
要求匹配位于指定的精确location
。距离1000
需要使用threshold
0.8
找到location
的800
字符以内的完美匹配。
ignoreLocation
bool
false
当true
时,搜索将忽略location
和distance
,因此模式出现在字符串中的位置并不重要。
提示:默认选项仅搜索前 60 个字符。如果合理预期匹配在此范围内,则这应该足够了。要修改此行为,请设置
location
、threshold
、distance
(或ignoreLocation
)的适当组合。为了更好地了解这些选项如何协同工作,请阅读 Fuse.js 的评分理论。
useExtendedSearch
bool
false
当true
时,它允许使用类 UNIX 搜索命令。参见示例。
getFn
callable
用于在提供的路径中检索对象值的函数。默认情况下还将搜索嵌套路径。
sortFn
callable
用于对所有结果进行排序的函数。默认情况下将按相关性分数升序、索引升序排序。
ignoreFieldNorm
bool
false
当true
时,相关性得分(用于排序)的计算将忽略字段长度范数。
提示:将
ignoreFieldNorm
设置为true
唯一有意义的情况是,无论有多少个术语,只要查询术语存在即可。
fieldNormWeight
float
1
确定字段长度范数对评分的影响程度。值0
相当于忽略字段长度范数。值为0.5
将大大降低字段长度范数的影响,而值为2.0
将大大增加它。
您可以通过config
方法访问和操作上述所有选项的默认值:
// Get an associative array of all options listed above
Fuse :: config ();
// Merge associative array of options into default config
Fuse :: config ([ ' shouldSort ' => false ]);
// Get single default option
Fuse :: config ( ' shouldSort ' );
// Set single default option
Fuse :: config ( ' shouldSort ' , false );
每个FuseFuse
实例都可以使用以下方法:
search
搜索整个文档集合,并返回搜索结果列表。
public function search( mixed $ pattern , ? array $ options ): array
$pattern
可以是以下之一:
$options
:
limit
(type: int
):表示返回搜索结果的最大数量。setCollection
设置/替换整个文档集合。如果未提供索引,则会生成一个。
public function setCollection( array $ docs , ? Fuse Core FuseIndex $ index ): void
例子:
$ fruits = [ ' apple ' , ' orange ' ];
$ fuse = new Fuse ( $ fruits );
$ fuse -> setCollection ([ ' banana ' , ' pear ' ]);
add
将文档添加到集合并相应地更新索引。
public function add( mixed $ doc ): void
例子:
$ fruits = [ ' apple ' , ' orange ' ];
$ fuse = new Fuse ( $ fruits );
$ fuse -> add ( ' banana ' );
sizeof ( $ fruits ); // => 3
remove
从列表中删除谓词返回 true 的所有文档,并返回已删除文档的数组。使用两个参数调用谓词: ($doc, $index)
。
public function remove(? callable $ predicate ): array
例子:
$ fruits = [ ' apple ' , ' orange ' , ' banana ' , ' pear ' ];
$ fuse = new Fuse ( $ fruits );
$ results = $ fuse -> remove (fn( $ doc ) => $ doc === ' banana ' || $ doc === ' pear ' );
sizeof ( $ fuse -> getCollection ()); // => 2
$ results ; // => ['banana', 'pear']
removeAt
删除指定索引处的文档。
public function removeAt( int $ index ): void
例子:
$ fruits = [ ' apple ' , ' orange ' , ' banana ' , ' pear ' ];
$ fuse = new Fuse ( $ fruits );
$ fuse -> removeAt ( 1 );
$ fuse -> getCollection (); // => ['apple', 'banana', 'pear']
getIndex
返回生成的 Fuse 索引。
public function getIndex(): Fuse Core FuseIndex
例子:
$ fruits = [ ' apple ' , ' orange ' , ' banana ' , ' pear ' ];
$ fuse = new Fuse ( $ fruits );
$ fuse -> getIndex ()-> size (); // => 4
每个FuseFuse
实例都可以使用以下方法:
Fuse::createIndex
从列表中预先生成索引,并将其直接传递到 Fuse 实例中。如果列表(相当)大,它会加快实例化速度。
public static function createIndex( array $ keys , array $ docs , array $ options = []): Fuse Core FuseIndex
例子:
$ list = [ ... ]; // See the example from the 'Usage' section
$ options = [ ' keys ' => [ ' title ' , ' author.firstName ' ] ];
// Create the Fuse index
$ myIndex = Fuse :: createIndex ( $ options [ ' keys ' ], $ list );
// Initialize Fuse with the index
$ fuse = new Fuse ( $ list , $ options , $ myIndex );
Fuse::parseIndex
解析 JSON 序列化的 Fuse 索引。
public static function parseIndex( array $ data , array $ options = []): Fuse Core FuseIndex
例子:
// (1) When the data is collected
$ list = [ ... ]; // See the example from the 'Usage' section
$ options = [ ' keys ' => [ ' title ' , ' author.firstName ' ] ];
// Create the Fuse index
$ myIndex = Fuse :: createIndex ( $ options [ ' keys ' ], $ list );
// Serialize and save it
file_put_contents ( ' fuse-index.json ' , json_encode ( $ myIndex ));
// (2) When the search is needed
// Load and deserialize index to an array
$ fuseIndex = json_decode ( file_get_contents ( ' fuse-index.json ' ), true );
$ myIndex = Fuse :: parseIndex ( $ fuseIndex );
// Initialize Fuse with the index
$ fuse = new Fuse ( $ list , $ options , $ myIndex );
Fuse.js | PHP熔断器 | |
---|---|---|
获取保险丝版本 | Fuse.version | – |
访问全局配置 | Fuse.config 属性 | Fuse::config 方法 |
列表修改 | 使用fuse.add() 等修改传递给new Fuse 构造函数的原始列表。 | 在 PHP 中,数组是一种原始数据类型,这意味着 Fuse 永远不会修改您的原始列表。要在添加/删除项目后接收当前列表,可以使用$fuse->getCollection() 方法。 |
请注意,我正在努力实现与 Fuse.js 的功能对等,因此不会向 Fuse.js 本身未反映的搜索逻辑添加功能或修复。
如果您对搜索结果有任何问题,但在这个 PHP 端口中不是明显的错误,并且您碰巧了解 JavaScript,请检查您的用例是否在 Fuse.js 的在线演示中正常工作,因为这是规范的 Fuse 实现。如果问题也出现在那里,请在他们的存储库中打开一个问题。
要开始在 Fuse 上进行开发,您需要 git、PHP (≥ 7.4) 和 Composer。
由于代码是使用 Prettier 格式化的,因此还建议安装 Node.js/npm 以及使用支持 Prettier 格式化的编辑器。
克隆存储库并cd
到其中:
git clone https://github.com/loilo/fuse.git
cd fuse
安装 Composer 依赖项:
composer install
安装 npm 依赖项(可选但推荐)。这仅在代码格式化时需要,因为 npm 依赖项包括该项目使用的 Prettier 插件。
npm ci
该项目有不同类型的代码检查。所有这些都在提交拉取请求时运行,但也可以在本地运行:
命令 | 目的 | 描述 |
---|---|---|
vendor/bin/phpcs | 检查代码风格 | 运行 PHP_CodeSniffer 以验证 Fuse 源代码是否遵循 PSR-12 编码风格。 |
vendor/bin/psalm | 静态分析 | 针对代码库运行 Psalm 以避免与类型相关的错误和不安全的编码模式。 |
vendor/bin/phpunit | 检查程序逻辑 | 从test 文件夹运行所有 PHPUnit 测试。 |
在提交拉取请求之前,请将相关测试添加到test
文件夹中。