이는 단순하면서도 기능적인 영어 및 러시아어 형태를 지원하는 콘텐츠 사이트용으로 설계된 검색 엔진입니다. 콘텐츠를 색인화하고 전체 텍스트 검색을 제공합니다.
데이터 베이스 | 테스트 |
---|---|
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 );
Indexer는 데이터를 특별한 형식으로 받아들입니다. 데이터는 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'))
모든 곳에서 검색합니다. 인덱싱할 때 인스턴스_id를 생략하거나 instance_id === null
제공하면 내부적으로 값 0
이 사용됩니다. 이러한 콘텐츠는 instance_id 제한이 없는 쿼리와만 일치할 수 있습니다.
Rose는 웹사이트 및 웹 애플리케이션용으로 설계되었습니다. 기본적으로 콘텐츠의 HTML 형식을 지원합니다. 그러나 다른 형식(예: 일반 텍스트, 마크다운)을 지원하도록 코드를 확장할 수 있습니다. 이는 사용자 정의 추출기를 생성하여 수행할 수 있습니다.
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에서는 구현되지 않습니다.