teamtnt / tntsearch
一个功能齐全的PHP全文搜索引擎
Requires
- php: ~7.1|^8
- ext-mbstring: *
- ext-pdo_sqlite: *
- ext-sqlite3: *
- predis/predis: ^2.2
Requires (Dev)
- phpunit/phpunit: 7.*|8.*|9.*
- symfony/var-dumper: ^4|^5.2
- dev-master
- v4.3.0
- v4.2.1
- v4.2.0
- v4.1.0
- v4.0.2
- v4.0.1
- v4.0.0
- v3.2.0
- v3.1.0
- v3.0.0
- v2.9.0
- v2.8.0
- v2.7.0
- v2.6.0
- v2.5.0
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.0
- v2.0.0
- v1.4.0
- v1.3.6
- v1.3.5
- v1.3.4
- v1.3.3
- v1.3.2
- v1.3.1
- v1.3.0
- v1.2.0
- v1.1.0
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v0.9.0
- v0.8.9
- v0.8.8
- v0.8.7
- v0.8.6
- v0.8.5
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.1
- v0.7.0
- v0.6.6
- v0.6.5
- v0.6.4
- v0.6.3
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.0
- v0.4.1
- v0.4.0
- v0.3.0
- v0.2.0
- v0.1.0
- dev-add-code-of-conduct-1
This package is auto-updated.
Last update: 2024-09-03 07:11:51 UTC
README
TNTSearch
TNTSearch 是一个完全用PHP编写的全文搜索引擎(FTS)。简单的配置允许您在几分钟内添加令人惊叹的搜索体验。功能包括
- 模糊搜索
- 边打边搜
- 地理搜索
- 文本分类
- 词干提取
- 自定义分词器
- Bm25 排名算法
- 布尔搜索
- 结果高亮显示
- 动态索引更新(无需每次都重新索引)
- 通过 Packagist.org 容易部署
我们还创建了一些演示页面,展示了使用 n-gram 的容错检索。该包包含一些辅助函数,如 Jaro-Winkler 和余弦相似度用于距离计算。它支持英语、克罗地亚语、阿拉伯语、意大利语、俄语、葡萄牙语和乌克兰语的词干提取。如果内置的词干提取器不够用,该引擎允许您轻松地插件任何兼容的 snowball 词干提取器。该包的一些分支甚至支持中文。请继续贡献其他语言!
与其他许多引擎不同,索引可以很容易地更新,而无需重新索引或使用增量。
查看 在线演示 | 关注我们 在 Twitter,或 Facebook | 访问我们的赞助商
演示
教程
高级产品
如果您在使用 TNT Search 并且觉得它很有用,请查看我们的高级分析工具
在 Open Collective 上支持我们
安装
安装 TNTSearch 最简单的方法是通过 composer
composer require teamtnt/tntsearch
要求
在继续之前,请确保您的服务器满足以下要求
- PHP >= 7.1
- PDO PHP 扩展
- SQLite PHP 扩展
- mbstring PHP 扩展
示例
创建索引
为了能够执行全文搜索查询,您必须创建一个索引。
用法
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig([ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'dbname', 'username' => 'user', 'password' => 'pass', 'storage' => '/var/www/tntsearch/examples/', 'stemmer' => \TeamTNT\TNTSearch\Stemmer\PorterStemmer::class//optional ]); $indexer = $tnt->createIndex('name.index'); $indexer->query('SELECT id, article FROM articles;'); //$indexer->setLanguage('german'); $indexer->run();
重要: "storage" 设置标记了所有索引将保存的文件夹,请确保您有写入此文件夹的权限,否则您可能会遇到以下异常
- [PDOException] SQLSTATE[HY000] [14] 无法打开数据库文件 *
注意:如果您的主键不同于 id
,请按以下方式设置
$indexer->setPrimaryKey('article_id');
使主键可搜索
默认情况下,主键不可搜索。如果您想使其可搜索,只需运行
$indexer->includePrimaryKey();
搜索
搜索短语或关键词很简单
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig($config); $tnt->selectIndex("name.index"); $res = $tnt->search("This is a test search", 12); print_r($res); //returns an array of 12 document ids that best match your query // to display the results you need an additional query against your application database // SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res);
ORDER BY FIELD 子句很重要,否则数据库引擎不会按所需顺序返回结果。
布尔搜索
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig($config); $tnt->selectIndex("name.index"); //this will return all documents that have romeo in it but not juliet $res = $tnt->searchBoolean("romeo -juliet"); //returns all documents that have romeo or hamlet in it $res = $tnt->searchBoolean("romeo or hamlet"); //returns all documents that have either romeo AND juliet or prince AND hamlet $res = $tnt->searchBoolean("(romeo juliet) or (prince hamlet)");
模糊搜索
可以通过设置以下成员变量来调整模糊度
public $fuzzy_prefix_length = 2; public $fuzzy_max_expansions = 50; public $fuzzy_distance = 2; //represents the Levenshtein distance;
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig($config); $tnt->selectIndex("name.index"); $tnt->fuzziness(true); //when the fuzziness flag is set to true, the keyword juleit will return //documents that match the word juliet, the default Levenshtein distance is 2 $res = $tnt->search("juleit");
更新索引
一旦创建了索引,您无需在更改文档集合时每次都重新索引它。TNTSearch 支持动态索引更新。
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig($config); $tnt->selectIndex("name.index"); $index = $tnt->getIndex(); //to insert a new document to the index $index->insert(['id' => '11', 'title' => 'new title', 'article' => 'new article']); //to update an existing document $index->update(11, ['id' => '11', 'title' => 'updated title', 'article' => 'updated article']); //to delete the document from index $index->delete(12);
自定义分词器
首先,创建您自己的分词器类。它应该继承自AbstractTokenizer类,定义单词拆分的$pattern值,并且必须实现TokenizerInterface接口。
use TeamTNT\TNTSearch\Support\AbstractTokenizer; use TeamTNT\TNTSearch\Support\TokenizerInterface; class SomeTokenizer extends AbstractTokenizer implements TokenizerInterface { static protected $pattern = '/[\s,\.]+/'; public function tokenize($text) { return preg_split($this->getPattern(), strtolower($text), -1, PREG_SPLIT_NO_EMPTY); } }
这个分词器将使用空格、逗号和句点来拆分单词。
准备好分词器后,应通过setTokenizer
方法将其传递给TNTIndexer
。
$someTokenizer = new SomeTokenizer; $indexer = new TNTIndexer; $indexer->setTokenizer($someTokenizer);
另一种方法是通过配置文件传递分词器。
use TeamTNT\TNTSearch\TNTSearch; $tnt = new TNTSearch; $tnt->loadConfig([ 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'dbname', 'username' => 'user', 'password' => 'pass', 'storage' => '/var/www/tntsearch/examples/', 'stemmer' => \TeamTNT\TNTSearch\Stemmer\PorterStemmer::class//optional, 'tokenizer' => \TeamTNT\TNTSearch\Support\SomeTokenizer::class ]); $indexer = $tnt->createIndex('name.index'); $indexer->query('SELECT id, article FROM articles;'); $indexer->run();
地理搜索
索引
$candyShopIndexer = new TNTGeoIndexer; $candyShopIndexer->loadConfig($config); $candyShopIndexer->createIndex('candyShops.index'); $candyShopIndexer->query('SELECT id, longitude, latitude FROM candy_shops;'); $candyShopIndexer->run();
搜索
$currentLocation = [ 'longitude' => 11.576124, 'latitude' => 48.137154 ]; $distance = 2; //km $candyShopIndex = new TNTGeoSearch(); $candyShopIndex->loadConfig($config); $candyShopIndex->selectIndex('candyShops.index'); $candyShops = $candyShopIndex->findNearest($currentLocation, $distance, 10);
分类
use TeamTNT\TNTSearch\Classifier\TNTClassifier; $classifier = new TNTClassifier(); $classifier->learn("A great game", "Sports"); $classifier->learn("The election was over", "Not sports"); $classifier->learn("Very clean match", "Sports"); $classifier->learn("A clean but forgettable game", "Sports"); $guess = $classifier->predict("It was a close election"); var_dump($guess['label']); //returns "Not sports"
保存分类器
$classifier->save('sports.cls');
加载分类器
$classifier = new TNTClassifier(); $classifier->load('sports.cls');
驱动程序
PS4Ware
您可以使用这个包,但如果它进入您的生产环境,我们非常希望您发送我们一款您选择的PS4游戏。这样,您可以支持我们进一步开发和添加新功能。
我们的地址是:TNT Studio,Sv. Mateja 19,10010 萨格勒布,克罗地亚。
我们将在此发布所有收到的游戏。
支持
赞助商
通过每月捐赠支持我们,帮助我们继续活动。[成为赞助商]
赞助商
成为赞助商,让您的标志出现在我们的Github README上,并附有链接到您的网站。[成为赞助商]
致谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。
来自克罗地亚,由TNT Studio(@tntstudiohr,博客)以♥制作