Dies ist eine Suchmaschine für Content-Websites mit vereinfachter, aber funktionaler Unterstützung für englische und russische Morphologie. Es indiziert Ihre Inhalte und bietet eine Volltextsuche.
Datenbank | Tests |
---|---|
MySQL 5.6 oder höher und MariaDB 10.2 oder höher | |
PostgreSQL (getestet auf Versionen 10...16) | |
SQLite (getestet auf 3.37.2) |
composer require s2/rose
Der Index kann in einer Datenbank oder in einer Datei gespeichert werden. Ein Speicher dient als Abstraktionsschicht, die Implementierungsdetails verbirgt. In den meisten Fällen benötigen Sie den Datenbankspeicher PdoStorage
.
Der Speicher wird sowohl für die Indizierung als auch für die Suche benötigt.
$ 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_ ' );
Wenn Sie den Index neu erstellen möchten, rufen Sie die Methode PdoStorage::erase()
auf:
$ storage -> erase ();
Es löscht Indextabellen (sofern vorhanden) und erstellt von Grund auf neue. Diese Methode reicht für ein Upgrade auf eine neue Version von Rose aus, die möglicherweise nicht abwärtskompatibel mit dem vorhandenen Index ist.
Für die Verarbeitung natürlicher Sprache verwendet Rose Stemmer. Der Wortstamm schneidet den flektierten Teil von Wörtern ab und Rose verarbeitet die resultierenden Wortstämme. Rose verfügt nicht über integrierte Wörterbücher, enthält jedoch von Porter entwickelte heuristische Stemmer. Sie können jeden anderen Algorithmus integrieren, indem Sie das StemmerInterface implementieren.
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
erstellt den Suchindex. Es kommt auf einen Stemmer und eine Lagerung an.
use S2 Rose Indexer ;
$ indexer = new Indexer ( $ storage , $ stemmer );
Indexer akzeptiert Ihre Daten in einem speziellen Format. Die Daten müssen in die Indexable
-Klasse eingeschlossen werden:
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 );
Der Konstruktor von Indexable
hat 4 Argumente:
Zu den optionalen Parametern, die Sie angeben können, gehören: Schlüsselwörter, Beschreibung, Datum, Relevanzverhältnis und URL. Schlüsselwörter werden indiziert und mit höherer Relevanz durchsucht. Die Beschreibung kann zum Erstellen eines Snippets verwendet werden (siehe unten). Es wird empfohlen, für diesen Zweck den Inhalt der Meta-Tags „Schlüsselwort“ und „Beschreibung“ (sofern verfügbar) zu verwenden. Die URL kann eine beliebige Zeichenfolge sein.
Die Methode Indexer::index()
wird sowohl zum Hinzufügen als auch zum Aktualisieren des Index verwendet. Wenn der Inhalt unverändert bleibt, überspringt diese Methode den Vorgang. Andernfalls wird der Inhalt entfernt und erneut indiziert.
Wenn Sie eine Seite von der Website entfernen, rufen Sie einfach an
$ indexer -> removeById ( $ externalId , $ instanceId );
Volltextsuchergebnisse können über Finder
-Klasse abgerufen werden. $resultSet->getItems()
gibt alle Informationen über Inhaltselemente und deren Relevanz zurück.
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>.'
}
Ändern Sie das Query
-Objekt, um eine Paginierung zu verwenden:
$ 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)
Geben Sie die Instanz-ID an, um den Suchumfang auf ein Subsystem einzuschränken:
$ resultSet = $ finder -> find (( new Query ( ' content ' ))-> setInstanceId ( 1 ));
foreach ( $ resultSet -> getItems () as $ item ) {
// first iteration only:
$ item -> getId (); // 'id_1'
$ item -> getInstanceId (); // 1
}
Es ist üblich, die gefundenen Wörter in den Suchergebnissen hervorzuheben. Sie können den hervorgehobenen Titel erhalten:
$ resultSet = $ finder -> find ( new Query ( ' title ' ));
$ resultSet -> getItems ()[ 0 ]-> getHighlightedTitle ( $ stemmer ); // 'Test page <i>title</i>'
Diese Methode erfordert den Stemmer, da sie die Morphologie berücksichtigt und alle Wortformen hervorhebt. Standardmäßig werden Wörter kursiv hervorgehoben. Sie können die Hervorhebungsvorlage ändern, indem Sie $finder->setHighlightTemplate('<b>%s</b>')
aufrufen.
Snippets sind kleine Textfragmente mit gefundenen Wörtern, die auf einer Suchergebnisseite angezeigt werden. Rose verarbeitet den indizierten Inhalt und wählt die am besten passenden Sätze aus.
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>.'
Wörter in den Snippets werden auf die gleiche Weise hervorgehoben wie in Titeln.
Wenn das Erstellen von Snippets viel Zeit in Anspruch nimmt, versuchen Sie, die Anzahl der verarbeiteten Snippets durch Paginierung zu reduzieren.
Instanzen können hilfreich sein, um den Suchumfang einzuschränken.
Sie können beispielsweise versuchen, Blogbeiträge mit instance_id = 1
und Kommentare mit instance_id = 2
zu indizieren. Anschließend können Sie Abfragen mit unterschiedlichen Einschränkungen ausführen:
(new Query('content'))->setInstanceId(1)
durchsucht Blogbeiträge,(new Query('content'))->setInstanceId(2)
durchsucht Kommentare,(new Query('content'))
sucht überall. Wenn Sie bei der Indizierung „instance_id“ weglassen oder instance_id === null
angeben, wird intern der Wert 0
verwendet. Solche Inhalte können nur Abfragen ohne Instanz-ID-Einschränkungen entsprechen.
Rose wurde für Websites und Webanwendungen entwickelt. Es unterstützt standardmäßig das HTML-Format des Inhalts. Es ist jedoch möglich, den Code zu erweitern, um andere Formate (z. B. Klartext, Markdown) zu unterstützen. Dies kann durch Erstellen eines benutzerdefinierten Extraktors erfolgen:
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 ist in der Lage, ähnliche Elemente innerhalb des gesamten Satzes indizierter Elemente zu identifizieren.
Stellen Sie sich ein Szenario vor, in dem Sie einen Blog haben und dessen Beiträge mit Rose indiziert werden. Mit dieser besonderen Funktion können Sie für jeden einzelnen Beitrag eine Reihe anderer Beiträge auswählen, sodass Besucher verwandte Inhalte erkunden können.
Die Datenstruktur innerhalb des Volltextindex eignet sich gut für die Aufgabe, ähnliche Beiträge auszuwählen. Um es einfach auszudrücken: Bei der regulären Suche werden relevante Beiträge anhand von Wörtern aus einer Suchanfrage ausgewählt, während bei Beitragsempfehlungen andere Beiträge anhand der in einem bestimmten Beitrag vorhandenen Wörter ausgewählt werden.
Sie können Empfehlungen abrufen, indem Sie die folgende Methode aufrufen:
$ 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.',
// ],
Notiz
Empfehlungen werden für MySQL- und PostgreSQL-Datenbanken unterstützt. Sie sind aufgrund der eingeschränkten SQL-Unterstützung nicht in SQLite implementiert.