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.