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ł

Dodaj komentarz

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

We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners. View more
Cookies settings
Accept
Privacy & Cookie policy
Privacy & Cookies policy
Cookie name Active
Save settings
Cookies settings