Ini adalah mesin pencari yang dirancang untuk situs konten dengan dukungan morfologi bahasa Inggris dan Rusia yang disederhanakan namun fungsional. Ini mengindeks konten Anda dan menyediakan pencarian teks lengkap.
Basis data | Tes |
---|---|
MySQL 5.6 atau lebih baru dan MariaDB 10.2 atau lebih baru | |
PostgreSQL (diuji pada versi 10...16) | |
SQLite (diuji pada 3.37.2) |
composer require s2/rose
Indeks dapat disimpan dalam database atau dalam file. Penyimpanan berfungsi sebagai lapisan abstraksi yang menyembunyikan detail implementasi. Dalam kebanyakan kasus, Anda memerlukan penyimpanan basis data PdoStorage
.
Penyimpanan diperlukan untuk pengindeksan dan pencarian.
$ 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_ ' );
Saat Anda ingin membangun kembali indeks, Anda memanggil metode PdoStorage::erase()
:
$ storage -> erase ();
Itu menghilangkan tabel indeks (jika ada) dan membuat yang baru dari awal. Metode ini cukup untuk meningkatkan ke versi baru Rose yang mungkin tidak kompatibel dengan indeks yang ada.
Untuk pemrosesan bahasa alami, Rose menggunakan stemmer. Stemmer memotong bagian kata yang diinfleksikan, dan Rose memproses batang yang dihasilkan. Rose tidak memiliki kamus bawaan, tetapi mencakup stemmer heuristik yang dikembangkan oleh Porter. Anda dapat mengintegrasikan algoritma lain dengan mengimplementasikan 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
membuat indeks pencarian. Itu tergantung pada stemmer dan tempat penyimpanan.
use S2 Rose Indexer ;
$ indexer = new Indexer ( $ storage , $ stemmer );
Pengindeks menerima data Anda dalam format khusus. Data harus dibungkus dalam kelas 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 );
Konstruktor Indexable
memiliki 4 argumen:
Parameter opsional yang dapat Anda berikan meliputi: kata kunci, deskripsi, tanggal, rasio relevansi, dan URL. Kata kunci diindeks dan dicari dengan relevansi lebih tinggi. Deskripsi dapat digunakan untuk membuat cuplikan (lihat di bawah). Disarankan untuk menggunakan konten meta-tag "kata kunci" dan "deskripsi", jika tersedia, untuk tujuan ini. URL dapat berupa string sembarang.
Metode Indexer::index()
digunakan untuk menambah dan memperbarui indeks. Jika kontennya tidak berubah, metode ini akan melewatkan operasi. Jika tidak, konten akan dihapus dan diindeks lagi.
Saat Anda menghapus halaman dari situs, cukup hubungi
$ indexer -> removeById ( $ externalId , $ instanceId );
Hasil pencarian teks lengkap dapat diperoleh melalui kelas Finder
. $resultSet->getItems()
mengembalikan semua informasi tentang item konten dan relevansinya.
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>.'
}
Ubah objek Query
untuk menggunakan 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)
Berikan id instance untuk membatasi cakupan pencarian dengan subsistem:
$ resultSet = $ finder -> find (( new Query ( ' content ' ))-> setInstanceId ( 1 ));
foreach ( $ resultSet -> getItems () as $ item ) {
// first iteration only:
$ item -> getId (); // 'id_1'
$ item -> getInstanceId (); // 1
}
Merupakan praktik umum untuk menyorot kata-kata yang ditemukan dalam hasil pencarian. Anda dapat memperoleh judul yang disorot:
$ resultSet = $ finder -> find ( new Query ( ' title ' ));
$ resultSet -> getItems ()[ 0 ]-> getHighlightedTitle ( $ stemmer ); // 'Test page <i>title</i>'
Metode ini memerlukan stemmer karena memperhitungkan morfologi dan menyoroti semua bentuk kata. Secara default, kata-kata disorot dengan huruf miring. Anda dapat mengubah templat sorotan dengan memanggil $finder->setHighlightTemplate('<b>%s</b>')
.
Cuplikan adalah fragmen teks kecil berisi kata-kata yang ditemukan yang ditampilkan di halaman hasil pencarian. Rose memproses konten yang diindeks dan memilih kalimat yang paling cocok.
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>.'
Kata-kata dalam cuplikan disorot dengan cara yang sama seperti pada judul.
Jika membuat cuplikan memerlukan banyak waktu, coba gunakan penomoran halaman untuk mengurangi jumlah cuplikan yang diproses.
Instance dapat berguna untuk membatasi cakupan pencarian.
Misalnya, Anda dapat mencoba mengindeks postingan blog dengan instance_id = 1
dan komentar dengan instance_id = 2
. Kemudian Anda dapat menjalankan kueri dengan batasan berbeda:
(new Query('content'))->setInstanceId(1)
mencari melalui postingan blog,(new Query('content'))->setInstanceId(2)
mencari melalui komentar,(new Query('content'))
mencari di mana-mana. Saat mengindeks, jika Anda menghilangkan instance_id atau memberikan instance_id === null
, nilai 0
akan digunakan secara internal. Konten tersebut hanya dapat mencocokkan kueri tanpa batasan instance_id.
Rose dirancang untuk situs web dan aplikasi web. Ini mendukung format konten HTML secara default. Namun, dimungkinkan untuk memperluas kode untuk mendukung format lain (misalnya teks biasa, penurunan harga). Hal ini dapat dilakukan dengan membuat ekstraktor khusus:
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 memiliki kemampuan untuk mengidentifikasi item serupa dalam seluruh rangkaian item yang diindeks.
Pertimbangkan skenario di mana Anda memiliki blog dan postingannya diindeks menggunakan Rose. Fitur khusus ini memungkinkan Anda memilih sekumpulan postingan lain untuk setiap postingan individual, memungkinkan pengunjung menjelajahi konten terkait.
Struktur data dalam indeks teks lengkap sangat cocok untuk tugas memilih postingan serupa. Sederhananya, pencarian reguler memerlukan pemilihan postingan yang relevan berdasarkan kata-kata dari permintaan pencarian, sedangkan rekomendasi postingan melibatkan pemilihan postingan lain berdasarkan kata-kata yang ada dalam postingan tertentu.
Anda dapat mengambil rekomendasi dengan menerapkan metode berikut:
$ 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.',
// ],
Catatan
Rekomendasi didukung pada database MySQL dan PostgreSQL. Mereka tidak diterapkan di SQLite karena terbatasnya dukungan SQL.