TNTSearch — это система полнотекстового поиска (FTS), полностью написанная на PHP. Простая конфигурация позволяет вам добавить потрясающие возможности поиска за считанные минуты. Особенности включают в себя:
Мы также создали несколько демонстрационных страниц, демонстрирующих толерантный поиск с использованием n-грамм в действии. В пакете есть множество вспомогательных функций, таких как Jaro-Winkler и Cosine подобие для расчета расстояний. Он поддерживает стемминг для английского, хорватского, арабского, итальянского, русского, португальского и украинского языков. Если встроенных стеммеров недостаточно, движок позволяет легко подключить любой совместимый стеммер Snowball. Некоторые версии пакета даже поддерживают китайский язык. И, пожалуйста, предложите другие языки!
В отличие от многих других движков, индекс можно легко обновить без повторного индексирования или использования дельт.
Посмотреть онлайн-демо | Следуйте за нами в Twitter или Facebook | Посетите наших спонсоров :
Если вы используете TNT Search и считаете его полезным, взгляните на наш премиум-инструмент аналитики:
Самый простой способ установить TNTSearch — через композитор:
composer require teamtnt/tntsearch
Прежде чем продолжить, убедитесь, что ваш сервер соответствует следующим требованиям:
Чтобы иметь возможность выполнять полнотекстовые поисковые запросы, вам необходимо создать индекс.
Использование:
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 ();
Важно: настройки «хранилище» отмечают папку, в которой будут сохранены все ваши индексы, поэтому убедитесь, что у вас есть разрешение на запись в эту папку, иначе вы можете ожидать возникновения следующего исключения:
Примечание. Если ваш первичный ключ отличается от 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 );
}
}
Этот токенизатор разделит слова с помощью пробелов, запятых и точек.
После того, как токенизатор готов, вам следует передать его TNTIndexer
с помощью метода setTokenizer
.
$ 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 ' );
Вы можете свободно использовать этот пакет, но если он появится в вашей производственной среде, мы будем очень признательны, если вы отправите нам игру для PS4 по вашему выбору. Таким образом, вы поддерживаете нас в дальнейшем развитии и добавлении новых функций.
Наш адрес: Студия ТНТ, Св. Матея 19, 10010 Загреб, Хорватия.
Все полученные игры мы будем публиковать здесь
Поддержите нас ежемесячным пожертвованием и помогите нам продолжить нашу деятельность. [Стать спонсором]
Станьте спонсором и разместите свой логотип в нашем README на Github со ссылкой на ваш сайт. [Стать спонсором]
Лицензия MIT (MIT). Дополнительную информацию см. в файле лицензии.
Из Хорватии с ♥ от TNT Studio (@tntstudiohr, блог)