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.

This post is also available in: angielski

This entry was posted on poniedziałek, Listopad 15th, 2010 at 08:31 and is filed under Autocomplete, Solr, Tutorial. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

13 komentarzy to “Solr i autocomplete (cz. 2)”

  1. Bald Says:

    Witam,

    Sciagnalem z SVN wersje 3, uruchomilem pod Windows (bez zadnych zmian w konfiguracji):

    java -jar start.jar

    2010-12-08 12:34:02.637:INFO::Logging to STDERR via org.mortbay.log.StdErrLog
    2010-12-08 12:34:02.732:INFO::jetty-6.1.26
    2010-12-08 12:34:02.767:INFO::Started SocketConnector@0.0.0.0:8983

    I po wklepaniu http://localhost:8983/solr/admin pojawia sie 404 :/ Zadnej informacji w logach nie ma 🙁 Czy ktos mial podobny problem?

  2. negativ Says:

    Nie używam windows, ale:
    – próbowałeś dodać ‚/’ na końcu adresu?
    – na pewno nie ma nic w logach? to co przedstawiłeś informuje tylko, że kontener jetty się podniósł, a nie, że nie było problemów z aplikacją
    – nie masz przypadkiem spacji w nazwie katalogu, w którym to zainstalowałeś?

    Generalnie wersja3 z wczoraj jeszcze działała poprawnie 😉

  3. Bald Says:

    Dzieki. Juz sobie poradzilem. Dziwne, ale po sciagnieciu paczki (nightbuilt) dziala ok, a po sciagnieciu prosto z SVN-a nie chcialo 😉

    Niemniej jednak dzieki za odpowiedz.

  4. Bald Says:

    Niestety, ten komponent nie dziala jak powinien :/ Podpowiadanie calych fraz jest ok, ale DOPOKI fraza nie zostanie oddziona spacja. Wowczas dokonuje podwojnego wyszukiwania.

    Czyli w tym przypadku bedzie po wpisaniu „dysk tw” zwroci sugestie dla slowa „dysk” oraz „tw” (osobno!).

  5. gr0 Says:

    Sprawdź jak masz zdefiniowane pole, które używasz do podpowiedzi, bo jeżeli masz oparte o typ który ma inny tokenizer niż solr.KeywordTokenizerFactory to na pewno podzieli frazę na słowa.

  6. Bald Says:

    Natomiast w konfiguracji:

    suggest
    org.apache.solr.spelling.suggest.Suggester
    org.apache.solr.spelling.suggest.tst.JasperLookup
    text_suggest
    true

    I dziala ladnie pod warunkiem, ze fraza jest np. „dy”. Wtedy zwraca „dysk twardy”, „dysk komputerowy” itp. Czyli na tym etapie jest ok.

    Ale gdy fraza jest „dysk tw” to oczekuje wynikow: „dysk twardy”, dysk twardy samsung”; a tymczasem solr zwraca mi podpowiedzi osobno, dla slow „dysk” jak i „tw”

  7. Bald Says:

    No i wycielo mi czesc komentarza 😉 Chcialem napisac, ze pole MAM zdefiniowane z tokenizerem solr.KeywordTokenizerFactory.

    I dziala ok, jezeli we frazie nie ma dwoch slow oddzielonych spacja.

  8. gr0 Says:

    Hmm… dziwne zachowanie, postaram się do tego zajrzeć jutro i dam znać jak to wygląda. Nie pamiętam, abym obserwował takie zachowanie.

  9. gr0 Says:

    Hmm komentarz mi się zgubił – moim zdaniem jedynym sposobem, aby zapobiec takiemu zachowaniu jak opisujesz jest użycie własnego query convertera, ale mogę się mylić.

  10. g0tan Says:

    Wszystko fajnie, prawie…;) Mam taki problem, że wpisując np. audi, chciałbym dostać podpowiedzi również „audi a3”, „audi a4”. Dlatego utworzyłem sobie copyField, gdzie pcham marke i model, ale wyszukiwanie po tym zwraca tylko dopasowanie konkretne? Jakieś sugestie co powinienem dodać, może jakaś konfiguracja do samego spellcheckera? Byłbym wdzięczny.

  11. Ola Says:

    A jak zrealizować takie coś w Solritas?

  12. gr0 Says:

    Trzeba zmodyfikować szablony velocity i wzbogacić je o wywołania ajaxowe.

  13. Solr i autocomplete (cz. 3) | Solr Enterprise Search Says:

    […] poprzednich częściach (cz. 1, cz. 2) cyklu dowiedzieliśmy w jaki sposób można wykorzystać Solr, aby uzyskać funkcjonalność […]