Zapytania wildcard i jak wygląda ich obsługa w Solr

Jeden z naszych czytelników zgłosił bardzo ciekawy problem, który można streścić do następującego pytania – „Dlaczego nie działają mi polskie litery z zapytaniach z wykorzystaniem wildcardów ?„. Ten wpis postara się odpowiedzieć na to pytanie.

Definicja typu i pola

Nasz czytelnik posiada następujący typ danych opisanych w pliku schema.xml:

<fieldType name="c_string" class="solr.TextField">
 <analyzer type="index">
  <tokenizer class="solr.KeywordTokenizerFactory"/>
  <filter class="solr.ASCIIFoldingFilterFactory"/>
  <filter class="solr.LowerCaseFilterFactory" />
  <filter class="solr.ReversedWildcardFilterFactory" />
 </analyzer>
 <analyzer type="query">
  <tokenizer class="solr.KeywordTokenizerFactory"/>
  <filter class="solr.ASCIIFoldingFilterFactory"/>
  <filter class="solr.LowerCaseFilterFactory" />
  <filter class="solr.ReversedWildcardFilterFactory" />
 </analyzer>
</fieldType>

Do tego pole, które jest obsługiwane przez ten typ wygląda następująco:

<field name="word" type="c_string" indexed="true" stored="true" />

Dane

Do testów opisywanego problemu wykorzystywałem następujące dane:

<add>
 <doc>
  <field name="id">1</field>
  <field name="word">Zażółć gęślą jaźń</field>
 </doc>
</add>

Definicja problemu

Problem został zdefiniowany następująco: „w polu word mam polskie znaki, ale gdy zrobię zapytanie z polskim znakiem, np. „word:*ą*” to nic mi nie znajdzie„.

O czym warto pamiętać korzystając z ReversedWildcardFilterFactory

Podczas korzystania z ReversedWildcardFilterFactory należy pamiętać, aby filter ten zdefiniować tylko dla analizy podczas indeksowania, a nie definiować go dla analizy zapytań. Zatem poprawiona definicja typu powinna wyglądać następująco:

<fieldType name="c_string" class="solr.TextField">
 <analyzer type="index">
  <tokenizer class="solr.KeywordTokenizerFactory"/>
  <filter class="solr.ASCIIFoldingFilterFactory"/>
  <filter class="solr.LowerCaseFilterFactory" />
  <filter class="solr.ReversedWildcardFilterFactory" />
 </analyzer>
 <analyzer type="query">
  <tokenizer class="solr.KeywordTokenizerFactory"/>
  <filter class="solr.ASCIIFoldingFilterFactory"/>
  <filter class="solr.LowerCaseFilterFactory" />
 </analyzer>
</fieldType>

Czy teraz już działa ?

Zadając następujące zapytanie:

http://localhost:8983/solr/select?q=word:*ś*

dalej nie otrzymujemy żadnych wyników. Dlaczego ?

Solr i obsługa wildcardów

Odpowiedź na pytanie postawione powyżej, jest dość prosta – Solr nie analizuje zapytań w których występują wildcardy. Tak, oznacza to, że podczas indeksacji filtr ASCIIFoldingFilterFactory usuwa nam polskie znaki zamieniając je na ich odpowiedniki z tablic 127 znaków ASCII, jednak w trakcie zadawania zapytania to się nie dzieje, pomimo tego, że filtry są zdefiniowane prawidłowo. I dlatego nie dostajemy żadnych wyników wyszukiwania. Jednak w takim wypadku, powinniśmy dostać wyniki zapytania na następujące zapytanie:

http://localhost:8983/solr/select?q=word:*s*

I tak się dokładnie dzieje, na powyższe zapytanie dostajemy wyniki wyszukiwania, jakich oczekiwaliśmy.

Możliwe rozwiązania

Jeżeli ktoś zapytał by mnie jakie rozwiązanie bym zasugerował, odpowiedziałbym, że w tym momencie po stronie aplikacji usuwałbym polskie znaki z zapytań które mają w sobie wildcardy. Od wersji 1.5 Solr, ReversedWildcardFilterFactory będzie poprawnie obsługiwać znaki spoza podstawowej tablicy ASCII, tak więc nie będzie konieczności korzystania z ASCIIFoldingFilterFactory, a co za tym idzie, problem nie będzie występował

This entry was posted on poniedziałek, Grudzień 20th, 2010 at 08:13 and is filed under Solr. 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.

2 komentarze to “Zapytania wildcard i jak wygląda ich obsługa w Solr”

  1. Piotrek Says:

    a tak mnie ostatnio zaciekawiło… co z Rosją, Grecją, Chinami? używanie solr’a jest tam możliwe? (pytanie niby głupie, ale skoro są polskie znaki jako „specjalne” to tam chyba całe alfabety? (może z Chinami przesadziłem:P))

  2. negativ Says:

    Daje radę. Co prawda jakość wsparcia dla różnych języków jest różna, ale działa. Łącznie z Chinami. Robiłem kiedyś chińską wyszukiwarkę i Chińczycy twierdzili że działa. Nie wiem jak z jakością, sam nie potrafiłem tego określić:)