Solr i autocomplete (cz. 2)

W poprzedniej części pokazałem w jaki sposób można wykorzystać mechanizm facetingu, aby zrealizować funkcjonalność autocomplete. Dzisiaj postaram pokazać jak wykorzystać komponent nazwany Suggest i za jego pomocą zrealizować funkcjonalność podpowiedzi.

Na początek

Jedna rzecz, którą należy powiedzieć – Suggest component nie jest dostępny w Solr w wersji 1.4.1 i niższych. Aby móc zacząć wykorzystywać ten komponent konieczne jest pobranie mininum wersji 3_x z repozytorium SVN.

Konfiguracja

Zanim przejdziemy do konfiguracji indeksu musimy zdefiniować komponent. A więc zaczynamy od zdefiniowania nowego komponentu wyszukiwania:

<searchComponent name="suggest" class="solr.SpellCheckComponent">
 <lst name="spellchecker">
  <str name="name">suggest</str>
  <str name="classname">org.apache.solr.spelling.suggest.Suggester</str>
  <str name="lookupImpl">org.apache.solr.spelling.suggest.tst.TSTLookup</str>
  <str name="field">name_autocomplete</str>
 </lst>
</searchComponent>

Warto wspomnieć, iż komponent Suggester oparty jest na solr.SpellCheckComponent dlatego konfiguracja wygląda tak jak powyżej. Mamy tutaj trzy ważne informacje:

  • name – nazwa komponentu.
  • lookupImpl – obiekt, który będzie obsługiwał wyszukiwanie. W tym momencie mamy dwie możliwości korzystanie z klasy TSTLookup lub JasperLookup. Ta pierwsza charakteryzuje się jednak większą wydajnością.
  • field – pole na podstawie, którego będą generowane podpowiedzi.

Dodajmy teraz odpowiedni handler, który będzie miał zapisaną odpowiednią konfigurację:

<requestHandler name="/suggest" class="org.apache.solr.handler.component.SearchHandler">
 <lst name="defaults">
  <str name="spellcheck">true</str>
  <str name="spellcheck.dictionary">suggest</str>
  <str name="spellcheck.count">10</str>
 </lst>
 <arr name="components">
  <str>suggest</str>
 </arr>
</requestHandler>

Dość prosta konfiguracja, która dla handlera definiuje dodatkowy komponent oraz mówi Solr, że maksymalna ilość pokazywanych podpowiedzi wynosi 10, ma być wykorzystywany spellchecker (a dokładniej Suggester) oraz, że słownik na podstawie, którego ma być realizowane podpowiadanie nazywa się suggest, czyli dokładnie tak samo jak nasz zdefiniowany komponent.

Indeks

Załóżmy, że nasz dokument składa się z 3 pól: identyfikatora, nazwy i opisu. Podpowiadanie realizujemy na podstawie pola przechowującego nazwę. Nasz indeks mógłby wyglądać nastęująco:

<field name="id" type="string" indexed="true" stored="true" multiValued="false" required="true"/>
<field name="name" type="text" indexed="true" stored="true" multiValued="false" />
<field name="name_autocomplete" type="text_auto" indexed="true" stored="true" multiValued="false" />
<field name="description" type="text" indexed="true" stored="true" multiValued="false" />

Dodatkowo dochodzi następująca definicja kopiowania pola:

<copyField source="name" dest="name_autocomplete" />

Podpowiadanie pojedynczych słów

Aby zrealizować podpowiadanie pojedynczych słów nasz typ text_autocomplete powinien zostać zdefiniowany w następujący sposób:

<fieldType class="solr.TextField" name="text_auto" positionIncrementGap="100">
 <analyzer>
  <tokenizer class="solr.WhitespaceTokenizerFactory"/>
  <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
  <filter class="solr.LowerCaseFilterFactory"/>
 </analyzer>
</fieldType>

Podpowiadanie fraz

Aby zrealizować podpowiadanie całych fraz nasz typ text_autocomplete powinien zostać zdefiniowany w następujący sposób:

<fieldType class="solr.TextField" name="text_auto">
 <analyzer>
  <tokenizer class="solr.KeywordTokenizerFactory"/>
  <filter class="solr.LowerCaseFilterFactory"/>
 </analyzer>
</fieldType>

Jeżeli chcemy podpowiadać całe frazy warto zastanowić się nad własną klasą odpowiedzialną za konwersję zapytań.

Budowanie słownika

Przed skorzystaniem z komponentu należy wybudować jego indeks. W tym celu wysyłamy następującą komendę:

/suggest?spellcheck.build=true

Zapytania

Teraz dochodzimy do wykorzystania komponentu. W celu pokazania jak wygląda wykorzystanie komponentu, zdecydowałem się na drugi wariant, czyli pełne frazy. Zadając zapytanie:

/suggest?q=dys

dostajemy następujące podpowiedzi:

<?xml version="1.0" encoding="UTF-8"?>
<response>
 <lst name="responseHeader">
  <int name="status">0</int>
  <int name="QTime">0</int>
 </lst>
 <lst name="spellcheck">
  <lst name="suggestions">
   <lst name="dys">
    <int name="numFound">4</int>
    <int name="startOffset">0</int>
    <int name="endOffset">3</int>
    <arr name="suggestion">
     <str>dysk twardy</str>
     <str>dysk twardy samsung</str>
     <str>dysk twardy seagate</str>
     <str>dysk twardy toshiba</str>
    </arr>
   </lst>
  </lst>
 </lst>
</response>

Na koniec

W kolejnej części dotyczącej funkcjonalności autocomplete zmodyfikujemy trochę wykorzystanie Suggestera i zobaczymy w jaki sposób dodać do mechanizmu słownik, aby jeszcze ulepszyć mechanizm podpowiedzi. Na ostatnią część zostawię sobie porównanie wydajności każdej z metod i sprawdzenia która z metod jest najszybsza w różnych sytuacjach.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *