這是一個專為內容網站設計的搜尋引擎,具有簡化但實用的英語和俄語形態支援。它為您的內容建立索引並提供全文搜尋。
資料庫 | 測試 |
---|---|
MySQL 5.6 或更高版本和 MariaDB 10.2 或更高版本 | |
PostgreSQL(在版本 10...16 上測試) | |
SQLite(在3.37.2上測試) |
composer require s2/rose
索引可以儲存在資料庫或檔案中。儲存充當隱藏實作細節的抽象層。在大多數情況下,您需要資料庫儲存PdoStorage
。
索引和搜尋都需要儲存。
$ 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_ ' );
當你想要重建索引時,你可以呼叫PdoStorage::erase()
方法:
$ storage -> erase ();
它刪除索引表(如果存在)並從頭開始建立新的索引表。此方法足以升級到可能無法向後相容現有索引的 Rose 新版本。
對於自然語言處理,Rose 使用詞幹分析器。詞幹分析器截斷單字的變形部分,Rose 處理生成的詞幹。 Rose 沒有內建字典,但包含 Porter 開發的啟發式字幹分析器。您可以透過實作 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
建立搜尋索引。這取決於詞幹分析器和儲存。
use S2 Rose Indexer ;
$ indexer = new Indexer ( $ storage , $ stemmer );
索引器以特殊格式接受您的資料。資料必須包裝在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 );
Indexable
的建構子有 4 個參數:
您可以提供的可選參數包括:關鍵字、描述、日期、相關性比率和 URL。關鍵字的索引和搜尋具有更高的相關性。此描述可用於建構片段(見下文)。為此,建議使用「關鍵字」和「描述」元標記的內容(如果可用)。 URL 可以是任意字串。
Indexer::index()
方法用於新增和更新索引。如果內容不變,則該方法會跳過該操作。否則,內容將被刪除並再次索引。
當您從網站中刪除頁面時,只需調用
$ indexer -> removeById ( $ externalId , $ instanceId );
全文搜尋結果可以透過Finder
類取得。 $resultSet->getItems()
傳回有關內容項目及其相關性的所有資訊。
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>.'
}
修改Query
物件以使用分頁:
$ 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)
提供實例 id 以限制子系統的搜尋範圍:
$ resultSet = $ finder -> find (( new Query ( ' content ' ))-> setInstanceId ( 1 ));
foreach ( $ resultSet -> getItems () as $ item ) {
// first iteration only:
$ item -> getId (); // 'id_1'
$ item -> getInstanceId (); // 1
}
在搜尋結果中突出顯示找到的單字是一種常見的做法。您可以獲得突出顯示的標題:
$ resultSet = $ finder -> find ( new Query ( ' title ' ));
$ resultSet -> getItems ()[ 0 ]-> getHighlightedTitle ( $ stemmer ); // 'Test page <i>title</i>'
此方法需要詞幹分析器,因為它考慮了形態並突出顯示了所有單字形式。預設情況下,單字以斜體突出顯示。您可以透過呼叫$finder->setHighlightTemplate('<b>%s</b>')
來變更突出顯示模板。
片段是包含在搜尋結果頁面上顯示的找到的單字的小文字片段。 Rose 處理索引內容並選擇最佳配對句子。
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>.'
片段中的單字以與標題中相同的方式突出顯示。
如果建立片段需要大量時間,請嘗試使用分頁來減少處理的片段數量。
實例有助於限制搜尋範圍。
例如,您可以嘗試使用instance_id = 1
為部落格文章建立索引,並使用instance_id = 2
為評論建立索引。然後您可以執行具有不同限制的查詢:
(new Query('content'))->setInstanceId(1)
透過部落格文章進行搜索,(new Query('content'))->setInstanceId(2)
透過評論進行搜索,(new Query('content'))
到處搜尋。建立索引時,如果省略 instance_id 或提供instance_id === null
,則內部將使用值0
。此類內容只能符合沒有instance_id限制的查詢。
Rose 專為網站和 Web 應用程式而設計。預設支援HTML格式的內容。但是,可以擴展程式碼以支援其他格式(例如純文字、Markdown)。這可以透過建立自訂提取器來完成:
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 能夠辨識整個索引項目集中的相似項目。
考慮這樣一個場景,您有一個博客,並且其帖子是使用 Rose 進行索引的。此特殊功能可讓您為每個單獨的帖子選擇一組其他帖子,使訪客能夠探索相關內容。
全文索引中的資料結構非常適合選擇相似貼文的任務。簡而言之,常規搜尋需要根據搜尋查詢中的單字選擇相關帖子,而帖子推薦則需要根據給定帖子中存在的單字選擇其他帖子。
您可以透過呼叫以下方法來檢索推薦:
$ 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.',
// ],
筆記
MySQL 和 PostgreSQL 資料庫支援建議。由於 SQL 支援有限,它們沒有在 SQLite 中實作。