rf1705 / tntsearch
一个功能齐全的PHP全文搜索引擎
Requires
- php: ~7.1|^8
- ext-mbstring: *
- ext-pdo_sqlite: *
- ext-sqlite3: *
- predis/predis: *
Requires (Dev)
- phpunit/phpunit: 7.*|8.*|9.*
- symfony/var-dumper: ^4|^5.2
- dev-master
- v4.2.3
- v4.2.2
- 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-patch-1
- dev-add-code-of-conduct-1
This package is auto-updated.
Last update: 2024-09-09 21:16:32 UTC
README
TNTSearch
TNTSearch是一个完全用PHP编写的全文搜索引擎(FTS)。简单的配置允许您在几分钟内添加令人惊叹的搜索体验。功能包括
- 模糊搜索
- 边打字边搜索
- 地理搜索
- 文本分类
- 词干提取
- 自定义分词器
- Bm25排名算法
- 布尔搜索
- 结果高亮显示
- 动态索引更新(无需每次都重新索引)
- 通过Packagist.org轻松部署
我们还创建了一些演示页面,展示了使用n-gram的容错检索。该包包含一些辅助函数,如Jaro-Winkler和余弦相似度,用于距离计算。它支持英语、克罗地亚语、阿拉伯语、意大利语、俄语、葡萄牙语和乌克兰语的词干提取。如果内置的词干提取器不足,该引擎允许您轻松地插件任何兼容的snowball词干提取器。该包的一些分支甚至支持中文。请为其他语言做出贡献!
与许多其他引擎不同,索引可以很容易地更新,而无需重新索引或使用delta。
查看 在线演示 | 关注我们 在 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);
自定义分词器
首先,创建您自己的Tokenizer类。它应该扩展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,博客)用♥制作