TNTSearch é um mecanismo de pesquisa de texto completo (FTS) escrito inteiramente em PHP. Uma configuração simples permite adicionar uma experiência de pesquisa incrível em apenas alguns minutos. Os recursos incluem:
Também criamos algumas páginas de demonstração que mostram a recuperação tolerante com n-gramas em ação. O pacote tem várias funções auxiliares, como Jaro-Winkler e similaridade de cosseno para cálculos de distância. Suporta lematização para inglês, croata, árabe, italiano, russo, português e ucraniano. Se os lematizadores integrados não forem suficientes, o mecanismo permite que você conecte facilmente qualquer lematizador de bola de neve compatível. Alguns garfos do pacote suportam até mesmo chinês. E por favor contribua com outros idiomas!
Ao contrário de muitos outros mecanismos, o índice pode ser facilmente atualizado sem fazer uma reindexação ou usar deltas.
Ver demonstração online | Siga-nos no Twitter ou Facebook | Visite nossos patrocinadores :
Se você estiver usando o TNT Search e achar que é útil, dê uma olhada em nossa ferramenta de análise premium:
A maneira mais fácil de instalar o TNTSearch é através do compositor:
composer require teamtnt/tntsearch
Antes de prosseguir, certifique-se de que seu servidor atenda aos seguintes requisitos:
Para poder fazer consultas de pesquisa de texto completo, você deve criar um índice.
Uso:
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 ();
Importante: as configurações de "armazenamento" marcam a pasta onde todos os seus índices serão salvos, portanto, certifique-se de ter permissão para gravar nesta pasta, caso contrário você poderá esperar a seguinte exceção:
Nota: Se sua chave primária for diferente de id
defina-a como:
$ indexer -> setPrimaryKey ( ' article_id ' );
Por padrão, a chave primária não é pesquisável. Se você quiser torná-lo pesquisável, basta executar:
$ indexer -> includePrimaryKey ();
Pesquisar uma frase ou palavra-chave é trivial:
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);
A cláusula ORDER BY FIELD é importante, caso contrário o mecanismo de banco de dados não retornará os resultados na ordem exigida.
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) " );
A imprecisão pode ser ajustada definindo as seguintes variáveis de membro:
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 " );
Depois de criar um índice, você não precisa reindexá-lo sempre que fizer alterações em sua coleção de documentos. TNTSearch oferece suporte a atualizações dinâmicas de índice.
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 );
Primeiro, crie sua própria classe Tokenizer. Ele deve estender a classe AbstractTokenizer, definir o valor $pattern da divisão da palavra e deve implementar 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 );
}
}
Este tokenizer dividirá as palavras usando espaços, vírgulas e pontos.
Depois de ter o tokenizer pronto, você deve passá-lo para TNTIndexer
através do método setTokenizer
.
$ someTokenizer = new SomeTokenizer ;
$ indexer = new TNTIndexer ;
$ indexer -> setTokenizer ( $ someTokenizer );
Outra forma seria passar o tokenizer via configuração:
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 ' );
Você é livre para usar este pacote, mas se ele chegar ao seu ambiente de produção, agradeceríamos muito se você nos enviasse um jogo PS4 de sua escolha. Dessa forma, você nos ajuda a desenvolver e adicionar novos recursos.
Nosso endereço é: TNT Studio, Sv. Mateja 19, 10010 Zagreb, Croácia.
Publicaremos todos os jogos recebidos aqui
Apoie-nos com uma doação mensal e ajude-nos a continuar nossas atividades. [Torne-se um apoiador]
Torne-se um patrocinador e coloque seu logotipo em nosso README no Github com um link para seu site. [Torne-se um patrocinador]
A licença MIT (MIT). Consulte Arquivo de licença para obter mais informações.
Da Croácia com ♥ por TNT Studio (@tntstudiohr, blog)