Il s'agit d'un moteur de recherche conçu pour les sites de contenu avec un support morphologique simplifié mais fonctionnel en anglais et en russe. Il indexe votre contenu et propose une recherche en texte intégral.
Base de données | Essais |
---|---|
MySQL 5.6 ou version ultérieure et MariaDB 10.2 ou version ultérieure | |
PostgreSQL (testé sur les versions 10...16) | |
SQLite (testé sur 3.37.2) |
composer require s2/rose
L'index peut être stocké dans une base de données ou dans un fichier. Un stockage sert de couche d'abstraction qui masque les détails de mise en œuvre. Dans la plupart des cas, vous avez besoin d'un stockage de base de données PdoStorage
.
Le stockage est requis à la fois pour l’indexation et la recherche.
$ pdo = new PDO ( ' mysql:host=127.0.0.1;dbname=s2_rose_test;charset=utf8 ' , ' username ' , ' passwd ' );
$ pdo -> setAttribute ( PDO :: ATTR_ERRMODE , PDO :: ERRMODE_EXCEPTION );
use S2 Rose Storage Database PdoStorage ;
$ storage = new PdoStorage ( $ pdo , ' table_prefix_ ' );
Lorsque vous souhaitez reconstruire l'index, vous appelez la méthode PdoStorage::erase()
:
$ storage -> erase ();
Il supprime les tables d'index (si elles existent) et en crée de nouvelles à partir de zéro. Cette méthode est suffisante pour mettre à niveau vers une nouvelle version de Rose qui peut ne pas être rétrocompatible avec l'index existant.
Pour le traitement du langage naturel, Rose utilise des stemmers. Le stemmer tronque la partie fléchie des mots et Rose traite les radicaux résultants. Rose n'a pas de dictionnaires intégrés, mais il inclut des stemmers heuristiques développés par Porter. Vous pouvez intégrer n’importe quel autre algorithme en implémentant StemmerInterface.
use S2 Rose Stemmer PorterStemmerEnglish ;
use S2 Rose Stemmer PorterStemmerRussian ;
// For optimization primary language goes first (in this case Russian)
$ stemmer = new PorterStemmerRussian ( new PorterStemmerEnglish ());
Indexer
construit l'index de recherche. Cela dépend d'un égrappoir et d'un stockage.
use S2 Rose Indexer ;
$ indexer = new Indexer ( $ storage , $ stemmer );
Indexer accepte vos données dans un format spécial. Les données doivent être encapsulées dans la classe Indexable
:
use S2 Rose Entity Indexable ;
// Main parameters
$ indexable = new Indexable (
' id_1 ' , // External ID - an identifier in your system
' Test page title ' , // Title
' This is the first page to be indexed. I have to make up a content. ' ,
1 // Instance ID - an optional ID of your subsystem
);
// Other optional parameters
$ indexable
-> setKeywords ( ' singlekeyword, multiple keywords ' ) // The same as Meta Keywords
-> setDescription ( ' Description can be used in snippets ' ) // The same as Meta Description
-> setDate ( new DateTime ( ' 2016-08-24 00:00:00 ' ))
-> setUrl ( ' url1 ' )
-> setRelevanceRatio ( 3.14 ) // Multiplier for important pages
;
$ indexer -> index ( $ indexable );
$ indexable = new Indexable (
' id_2 ' ,
' Test page title 2 ' ,
' This is the second page to be indexed. Let ' s compose something new. '
);
$ indexable -> setKeywords ( ' content, page ' );
$ indexer -> index ( $ indexable );
Le constructeur d' Indexable
a 4 arguments :
Les paramètres facultatifs que vous pouvez fournir incluent : les mots-clés, la description, la date, le taux de pertinence et l'URL. Les mots-clés sont indexés et recherchés avec une plus grande pertinence. La description peut être utilisée pour créer un extrait (voir ci-dessous). Il est suggéré d'utiliser à cette fin le contenu des balises méta « mot-clé » et « description », si elles sont disponibles. L'URL peut être une chaîne arbitraire.
La méthode Indexer::index()
est utilisée à la fois pour ajouter et mettre à jour l’index. Si le contenu est inchangé, cette méthode ignore l'opération. Sinon, le contenu est supprimé et à nouveau indexé.
Lorsque vous supprimez une page du site, appelez simplement
$ indexer -> removeById ( $ externalId , $ instanceId );
Les résultats de la recherche en texte intégral peuvent être obtenus via la classe Finder
. $resultSet->getItems()
renvoie toutes les informations sur les éléments de contenu et leur pertinence.
use S2 Rose Finder ;
use S2 Rose Entity Query ;
$ finder = new Finder ( $ storage , $ stemmer );
$ resultSet = $ finder -> find ( new Query ( ' content ' ));
foreach ( $ resultSet -> getItems () as $ item ) {
// first iteration: second iteration:
$ item -> getId (); // 'id_2' 'id_1'
$ item -> getInstanceId (); // null 1
$ item -> getTitle (); // 'Test page title 2' 'Test page title'
$ item -> getUrl (); // '' 'url1'
$ item -> getDescription (); // '' 'Description can be used in snippets'
$ item -> getDate (); // null new DateTime('2016-08-24 00:00:00')
$ item -> getRelevance (); // 4.1610856664112195 0.26907154598642522
$ item -> getSnippet (); // 'This is the second page...' 'I have to make up a <i>content</i>.'
}
Modifiez l'objet Query
pour utiliser une pagination :
$ query = new Query ( ' content ' );
$ query
-> setLimit ( 10 ) // 10 results per page
-> setOffset ( 20 ) // third page
;
$ resultSet = $ finder -> find ( $ query );
$ resultSet -> getTotalCount (); // Returns total amount of found items (for pagination links)
Fournissez l'ID d'instance pour limiter la portée de la recherche avec un sous-système :
$ resultSet = $ finder -> find (( new Query ( ' content ' ))-> setInstanceId ( 1 ));
foreach ( $ resultSet -> getItems () as $ item ) {
// first iteration only:
$ item -> getId (); // 'id_1'
$ item -> getInstanceId (); // 1
}
Il est courant de mettre en évidence les mots trouvés dans les résultats de recherche. Vous pouvez obtenir le titre en surbrillance :
$ resultSet = $ finder -> find ( new Query ( ' title ' ));
$ resultSet -> getItems ()[ 0 ]-> getHighlightedTitle ( $ stemmer ); // 'Test page <i>title</i>'
Cette méthode nécessite le stemmer puisqu'elle prend en compte la morphologie et met en évidence toutes les formes des mots. Par défaut, les mots sont mis en évidence en italique. Vous pouvez modifier le modèle de surbrillance en appelant $finder->setHighlightTemplate('<b>%s</b>')
.
Les extraits sont de petits fragments de texte contenant des mots trouvés qui sont affichés sur une page de résultats de recherche. Rose traite le contenu indexé et sélectionne les phrases les mieux adaptées.
use S2 Rose Entity ExternalContent ;
use S2 Rose Snippet SnippetBuilder ;
$ finder -> setSnippetLineSeparator ( ' · ' ); // Set snippet line separator. Default is '... '.
$ resultSet -> getItems ()[ 0 ]-> getSnippet ();
// 'I have to make up a <i>content</i>. · I have changed the <i>content</i>.'
Les mots dans les extraits sont mis en évidence de la même manière que dans les titres.
Si la création d'extraits de code prend beaucoup de temps, essayez d'utiliser la pagination pour réduire le nombre d'extraits traités.
Les instances peuvent être utiles pour restreindre la portée de la recherche.
Par exemple, vous pouvez essayer d'indexer les articles de blog avec instance_id = 1
et les commentaires avec instance_id = 2
. Ensuite, vous pouvez exécuter des requêtes avec différentes restrictions :
(new Query('content'))->setInstanceId(1)
recherche dans les articles de blog,(new Query('content'))->setInstanceId(2)
recherche dans les commentaires,(new Query('content'))
recherche partout. Lors de l'indexation, si vous omettez instance_id ou fournissez instance_id === null
, une valeur 0
sera utilisée en interne. Un tel contenu ne peut correspondre qu'à des requêtes sans restrictions instance_id.
Rose est conçu pour les sites Web et les applications Web. Il prend en charge le format HTML du contenu par défaut. Cependant, il est possible d'étendre le code pour prendre en charge d'autres formats (par exemple texte brut, démarque). Cela peut être fait en créant un extracteur personnalisé :
use S2 Rose Extractor ExtractorInterface ;
use S2 Rose Indexer ;
class CustomExtractor implements ExtractorInterface
{
// ...
// Please refer to the source code
// to figure out how to create an extractor.
}
$ indexer = new Indexer ( $ storage , $ stemmer , new CustomExtractor (), new Logger ());
PdoStorage a la capacité d'identifier des éléments similaires dans l'ensemble des éléments indexés.
Prenons un scénario dans lequel vous avez un blog et ses articles sont indexés à l'aide de Rose. Cette fonctionnalité particulière vous permet de choisir un ensemble d'autres publications pour chaque publication individuelle, permettant aux visiteurs d'explorer le contenu associé.
La structure des données au sein de l'index de texte intégral est bien adaptée à la tâche de sélection de publications similaires. Pour faire simple, la recherche régulière implique la sélection de publications pertinentes en fonction des mots d'une requête de recherche, tandis que les recommandations de publication impliquent la sélection d'autres publications en fonction des mots présents dans une publication donnée.
Vous pouvez récupérer des recommandations en appelant la méthode suivante :
$ similarItems = $ readStorage -> getSimilar ( new ExternalId ( ' id_2 ' ));
// The result contains the following data:
// $similarItems[0] = [
// 'tocWithMetadata' => new TocEntryWithMetadata(...),
// 'external_id' => 'id_1',
// 'instance_id' => '1',
// 'title' => 'Test page title',
// 'snippet' => 'This is the first page to be indexed.',
// 'snippet2' => 'I have to make up a content.',
// ],
Note
Les recommandations sont prises en charge sur les bases de données MySQL et PostgreSQL. Ils ne sont pas implémentés dans SQLite en raison d'une prise en charge limitée de SQL.