Autcomplete, cz. 4 (Ngram i faceting)

W poprzednich częściach przedstawiliśmy dwie metody tworzenia podpowiadania zapytań. Następnie jedną z nich rozbudowaliśmy o możliwość dodatkowego definiowania zwracanych informacji. W tym artykule wrócimy ponownie wykorzystamy faceting oraz ngram.

Wymagania

Przy tworzeniu listy podpowiedzi przyjęliśmy następujące założenia:

  1. Podpowiadana jest cała fraza a nie tylko pojedyncze słowo
  2. Podpowiadana fraza może wystąpić w indeksie wielokrotnie
  3. w wyniku chcemy znać liczbę wystąpień
  4. Częściej występujące frazy są podpowiadane w pierwszej kolejności
  5. Kolejność podawanych przez użytkownika słów nie musi odpowiadać kolejności występowania słów w podpowiadanej frazie

Rozwiązanie

Podany w pierwszej części sposób odpada ze względu na pierwsze założenie. Co prawda wyszukiwanie słów we frazie da się prosto osiągnąć zmieniając sposób analizy, jednak zwracane są pojedyncze słowa a nie cała fraza.

Rozwiązanie to zmodyfikowana wersja sposobu z facetingiem. Zamiast stosować wyszukiwanie wszystkich elementów i zawężanie wyników facetingu poprzez facet.prefix, możemy od razu wyszukać tylko te elementy, które mają fragment słowa wpisanego przez użytkownika. Ponieważ nie chcemy stosować zapytania prefiksowego ( „słowo*” ) ze względów wydajnościowych, na pomoc wezwiemy ngramy. Oznacza to zapisanie w indeksie wszystkich przedrostków słowa. Oczywistą wadą jest rozrost indeksu, ale w naszym przypadku jesteśmy w stanie z tym żyć 🙂

Schema.xml

Definiujemy więc dodatkowy typ:

  <fieldType name="text_autocomplete" class="solr.TextField" positionIncrementGap="100">
    <analyzer type="index">
      <tokenizer class="solr.WhitespaceTokenizerFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
      <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
    </analyzer>
    <analyzer type="query">
      <tokenizer class="solr.WhitespaceTokenizerFactory"/>
      <filter class="solr.LowerCaseFilterFactory"/>
    </analyzer>
  </fieldType>

Oraz pola: to, którego wartość będziemy wyświetlać oraz te, służące do wyszukiwania:

<field name="tag_autocomplete" type="text_autocomplete" indexed="true" stored="true" omitNorms="true" omitTermFreqAndPositions="true"/>
<field name="tag" type="string" indexed="true" stored="true" />

Zostaje jeszcze odpowiedni copyField:

<copyField source="tag" dest="tag_autocomplete"/>

 Zapytanie

Po przeindeksowaniu możemy przystąpić do tworzenia zapytania:

  1. Zawężamy listę wyników do tych, które w polu tag_autocomplete mają poszukiwany fragment słowa: q=tag_autocomplete:(FRAZA)
  2. W przypadku wielu podanych przez użytkownika fragmentów słów istotne jest, by były one wyszukiwane wszystkie: q.op=AND
  3. Tak naprawdę wyniki nie są istotne, dane odczytamy z facetingu, więc informujemy solr, że nie potrzebujemy listy wyników: rows=0
  4. Potrzebujemy natomiast faceting: facet=true
  5. W dodatku to faceting po polu w którym przechowujemy oryginalną zawartość pola podpowiedzi: facet.field=tag
  6. Nie interesują nas tagi, które nie zostały znalezione: facet.mincount=1
  7. Interesuje nas 5 wyników: facet.limit=5

Ostateczne zapytanie:

?q=tag_autocomplete:(FRAZA)&q.op=AND&rows=0&facet=true&facet.field=tag&facet.mincount=1&facet.limit=5

Jeśli parametry, które są stałe umieścimy w handlerze, jako wartości domyślne, to zapytanie sprowadza się do:

?q=tag_autocomplete:(FRAZA)

Słowo na koniec

Podstawową zaletą tego rozwiązania w stosunku do rozwiązania opartego o faceting i facet.prefix jest możliwość używania innego pola do zwracania podpowiedzi. Dzięki temu przy podpowiadaniu pojedynczych słów możemy w wyniku wyświetlić całą zawartość pola „tag”.

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