Install TNTSearch via Composer
masterThe easiest way to install TNTSearch is via Composer.
composer require teamtnt/tntsearchrepository·master·Indexed 25 days ago
https://github.com/teamtnt/tntsearchA full-text search engine written entirely in PHP. TNTSearch provides advanced search features including fuzzy search, boolean search, geo-search, and text classification without requiring external search services. It supports multiple database connectors (MySQL, PostgreSQL, Oracle, SQL Server) and allows for custom tokenizers and stemmers.
The easiest way to install TNTSearch is via Composer.
composer require teamtnt/tntsearchGeo search requires using TNTGeoIndexer for indexing and TNTGeoSearch for querying.
TNTGeoIndexer to index documents containing longitude and latitude.TNTGeoSearch::findNearest($currentLocation, $distance, $limit) where $currentLocation is an array with longitude and latitude keys.// Indexing
$candyShopIndexer = new TNTGeoIndexer;
$candyShopIndexer->loadConfig($config);
$candyShopIndexer->createIndex('candyShops.index');
$candyShopIndexer->query('SELECT id, longitude, latitude FROM candy_shops;');
$candyShopIndexer->run();
// Searching
$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);TNTSearch supports dynamic updates without requiring a full reindex. Use getIndex() to retrieve the index object, then use insert(), update(), or delete() to modify the document collection.
$tnt->selectIndex("name.index");
$index = $tnt->getIndex();
// Insert
$index->insert(['id' => '11', 'title' => 'new title', 'article' => 'new article']);
// Update
$index->update(11, ['id' => '11', 'title' => 'updated title', 'article' => 'updated article']);
// Delete
$index->delete(12);To enable full-text search, you must create an index using createIndex(). You define the data source using a SQL query via query() and then execute the indexing process with run().
If your primary key is not id, use setPrimaryKey('your_key'). You can also make the primary key searchable by calling includePrimaryKey().
use TeamTNT\TNTSearch\TNTSearch;
$tnt = new TNTSearch;
$tnt->loadConfig([
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'dbname',
'username' => 'user',
'password' => 'pass',
'storage' => '/var/www/tntsearch/examples/',
]);
$indexer = $tnt->createIndex('name.index');
$indexer->query('SELECT id, article FROM articles;');
//$indexer->setPrimaryKey('article_id');
//$indexer->includePrimaryKey();
$indexer->run();Use loadConfig() to set up the search engine. Required configuration includes database connection details and a storage path where indexes will be saved. The storage directory must be writable by the server, otherwise a [PDOException] SQLSTATE[HY000] [14] unable to open database file will be thrown.
Optional configuration keys:
stemmer: A class name for a compatible snowball stemmer.tokenizer: A class name for a custom tokenizer.$tnt->loadConfig([
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'dbname',
'username' => 'user',
'password' => 'pass',
'storage' => '/var/www/tntsearch/examples/',
'stemmer' => \TeamTNT\TNTSearch\Stemmer\PorterStemmer::class // optional
]);To use TNTSearch, instantiate the TNTSearch class and call loadConfig() with an associative array. The configuration can specify the storage path and the search engine. If no engine is specified, it defaults to TeamTNT\TNTSearch\Engines\SqliteEngine.
Note: If storage is provided, it is automatically rtrimmed and appended with a trailing slash.
Use searchBoolean() to perform complex queries using boolean logic:
- (NOT): romeo -juliet (contains romeo but not juliet)or (OR): romeo or hamlet (contains either romeo or hamlet)() (Grouping): (romeo juliet) or (prince hamlet)$res = $tnt->searchBoolean("romeo -juliet");
$res = $tnt->searchBoolean("romeo or hamlet");
$res = $tnt->searchBoolean("(romeo juliet) or (prince hamlet)");Enable fuzzy search by calling fuzziness(true). This allows for typo tolerance (e.g., searching for 'juleit' will match 'juliet').
Fuzziness behavior can be tuned via these properties:
$fuzzy_prefix_length: Minimum prefix length.$fuzzy_max_expansions: Maximum number of expansions.$fuzzy_distance: Levenshtein distance (default is 2).$tnt->selectIndex("name.index");
$tnt->fuzziness(true);
$res = $tnt->search("juleit");To use a custom tokenizer, create a class that extends AbstractTokenizer and implements TokenizerInterface. You must define a protected $pattern and implement the tokenize($text) method.
You can apply the tokenizer by passing it to setTokenizer() on a TNTIndexer instance or by including its class name in the loadConfig() array under the tokenizer key.
use TeamTNT\TNTSearch\Tokenizer\AbstractTokenizer;
use TeamTNT\TNTSearch\Tokenizer\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);
}
}
// Usage via config
$tnt->loadConfig([
// ... other config
'tokenizer' => \TeamTNT\TNTSearch\Tokenizer\SomeTokenizer::class
]);After selecting an index with selectIndex(), use search() to find documents. The method returns an array of document IDs that best match the query.
Note: To display results in the correct relevance order, you must perform an additional query against your application database using an ORDER BY FIELD(id, ...) clause.
use TeamTNT\TNTSearch\TNTSearch;
$tnt = new TNTSearch;
$tnt->loadConfig($config);
$tnt->selectIndex("name.index");
$res = $tnt->search("This is a test search", 12);
// To retrieve full records in order:
// SELECT * FROM articles WHERE id IN $res ORDER BY FIELD(id, $res);The TNTClassifier allows you to train a model to predict labels for text.
learn($text, $label) to train the classifier with examples.predict($text) to get a prediction. It returns an array containing the predicted 'label'.save($path) and load($path) to persist the classifier.use TeamTNT\TNTSearch\Classifier\TNTClassifier;
$classifier = new TNTClassifier();
$classifier->learn("A great game", "Sports");
$classifier->learn("The election was over", "Not sports");
$guess = $classifier->predict("It was a close election");
var_dump($guess['label']); // returns "Not sports"
// Persistence
$classifier->save('sports.cls');
$classifier->load('sports.cls');When using the PostgresConnector, you can provide a configuration array to the connect() method to customize the connection. The following configuration keys are supported:
database (required): The name of the database.host (optional): The database host.port (optional): The database port.sslmode (optional): The SSL mode for the connection.charset (optional): The character set to use (defaults to utf8).timezone (optional): The database timezone to set.schema (optional): The database schema(s) to set in the search_path. This can be a string or an array of strings.application_name (optional): The application name used for monitoring via pg_stat_activity.