Mimo, że za największą siłę Elasticsearcha może być uważane wyszukiwanie pełnotekstowe, to bynajmniej nie jest to jedyny sposób w jaki możemy odpytywać o interesujące nas dane. Podobnie robią wszystkie wiodące wyszukiwarki internetowe (z Google na czele). Mimo, że na pierwszym miejscu stawiają na pojedyncze pole tekstowe, w które możemy wpisać co tylko chcemy, to dodatkowo umożliwiają przefiltrowanie wyników choćby pod kątem języka w jakim napisane jest dane znalezisko, czy okresu z jakiego ono pochodzi. Analogiczne funkcjonalności (oraz kilka innych) dostarcza nam Elasticsearch. Dziś chciałbym Wam o nich opowiedzieć.

Cykl artykułów "Uczymy się Elasticsearch"

Ten wpis jest częścią cyklu, w którym staram się pokazać w jaki sposób możesz zbudować przyjazną dla użytkownika wyszukiwarkę, wykorzystując do tego celu potężny silnik wyszukiwania jakim jest Elasticsearch.

Do tej pory w ramach cyklu ukazały się następujące artykuły:

  1. instalacja, uruchomienie i pierwsze zapytanie
  2. kilka słów na temat Elastic Stack
  3. przydatne narzędzia
  4. indeks odwrócony Apache Lucene
  5. wyszukiwanie pełnotekstowe
  6. trafność
  7. przygotowanie tekstu do optymalnego wyszukiwania
  8. coś poszło nie tak, czyli seria moich fackupów
  9. zaczarowany zakreślacz
  10. o co jeszcze możemy zapytać?
  11. ...

Zapytania oparte o pełne wyrażenia

Dla przypomnienia, w wyszukiwaniu pełnotekstowym szukana fraza, zanim zostanie użyta, jest odpowiednio procesowana i analizowana. Dzięki temu jesteśmy w stanie uzyskać rezultaty niezależnie od wielkości liter, znaków diakrytycznych, czy odmiany słów. Nie wszystko jednak w życiu wymaga wyszukiwania pełnotekstowego. Wręcz przeciwnie. Istnieje wiele ustrukturyzowanych danych (liczbowych, wyliczeniowych, kalendarzowych, adresów IP, itp.), które aż się proszą o wyszukiwanie jeden do jednego. W tym miejscu z pomocą przychodzą zapytania określane w dokumentacji Elasticsearcha jako term-level queries. Ich ogólna idea polega na tym, że wprowadzone zapytanie wykorzystywane jest bez żadnego analizowania.

Rodzaje zapytań

term, termsterms_set

Wśród zapytań typu term-level możemy zauważyć kilka podgrup. Do pierwszej z nich wpadają zapytania term, termsterms_set. Pozwalają wyszukać na przykład dane typu wyliczeniowego lub choćby identyfikatory.

Dla przykładu, poniższe zapytanie zwróci wszystkie dokumenty, których właścicielem (pole owner) będzie Robb Stark (wartość robbstark) lub Jon Snow (wartość jonsnow).

Zapytanie terms_set działa analogicznie dostarczając kilku dodatkowych opcji konfiguracji, a term zamiast listy przyjmuje jedno wyrażenie.

range

Kolejnym zapytaniem, przydatnym choćby przy filtrowaniu dat jest zapytanie range. Przykładowo poniższe zapytanie wyszuka wszystkie osoby urodzone (pole born) od 5 sierpnia 1986 roku do dziś. Przy czym „dziś” będzie zmieniało się automatycznie.

Fajne jest to, że Elasticsearch pozwala w tym miejscu specyfikować daty na wiele sposobów, a oprócz dat mamy również możliwość wyszukiwania zakresów liczbowych oraz tekstowych.

exists (+ missing)

Żeby zwrócić dokumenty, które w danym polu zawierają przynajmniej „jedną nie-null-ową wartość” używamy zapytania exists:

Musimy jednak uważać co to dla nas oznacza. Spójrzmy jak zachowa się powyższe zapytanie z różnymi rodzajami dokumentów:

Elasticsearch nie dostarcza odrębnego zapytania missing, które zwracałoby dokumenty, w których jakieś określone pole jest pominięte. Możemy je skonstruować wykorzystując zapytanie exists:

prefix, wildcard, regexpfuzzy

Kolejną grupę zapytań możemy określić jako „dzwonią dzwony, ale nie wiadomo w którym kościele” 😉 Jeżeli coś tam gdzieś nam świta, coś kojarzymy, ale nie jesteśmy pewni dokładnej wartości albo kojarzymy tylko fragment, to możemy użyć jednego z czterech poniższych zapytań:

  • prefix – wykorzystanie przedrostka
  • wildcard – użycie „dzikich kart” 😀
  • regexp – wykorzystanie wyrażeń regularnych
  • fuzzy – użycie odległości Levenshteina

type oraz ids

Pozostałe dwa zapytania możemy traktować jako nieco „techniczne”. Umożliwiają one bowiem wyszukiwanie dokumentów po identyfikatorach (ids) oraz typach (type) dokumentów.

Zapytania złożone

Mając tyle dostępnych klocków chcielibyśmy zapewne mieć możliwość ich składania. Mamy 🙂 Z pomocą przychodzi nam zapytanie bool, pozwalające robić coś takiego:

Zapytanie typu bool może opakowywać dowolne z poznanych przez nas zapytań w jedną z czterech grup: must, filter, must_not oraz should. Możliwości są więc praktycznie nieograniczone.

Oprócz tego Elasticsearch dostarcza jeszcze cztery inne zapytania opakowujące: constant_score, dis_max, function_score oraz boosting. Polecam przyjrzeć się im kiedy zachodzi potrzeba grubszej manipulacji trafnością.

Zapytania łączące

Elasticsearch dostarcza dwa typy danych (nested oraz join) umożliwiające odzwierciedlanie relacji pomiędzy dokumentami wewnątrz jednego indeksu, jednocześnie dając możliwość wyszukiwania po nich przy pomocy czterech zapytań: nested, has_child, has_parent oraz parent_id.

Zapytania geograficzne

Jedną z funkcjonalności Elasticsearcha, która bardzo wpadła mi w oko, a której nie miałem jeszcze okazji dobrze przetestować jest obsługa danych geograficznych. Do dyspozycji mamy dwa typy danych: geo_point przechowujący długość i szerokość geograficzną oraz geo_shape pozwalający odzwierciedlać kształty, które możemy odpytywać czterema zapytaniami.

Trzy z nich bazują na punktach: geo_bounding_box, geo_polygon oraz geo_distance. Umożliwiają sprawdzenie, czy odpytywane punkty zawierają się w określonym wielokącie lub leżą w pewnej odległości od zadanego punktu. Czwarte zapytanie, geo_shape, bazuje na kształtach i umożliwia sprawdzenie, czy porównywane obszary się przecinają, nie przecinają, czy może jeden zawiera w sobie drugi.

Zapytania specjalistyczne

Dokumentacja Elasticsearcha dostarcza nam grupę zapytań specjalistycznych, z zabawnym opisem: this group contains queries which do not fit into the other groups 😉 Do tego worka wpadły zapytania: more_like_this, script, percolate, a także wrapper.

more_like_this umożliwia wyszukiwanie dokumentów, które są w określony sposób podobne do grupy innych, określonych przez nas dokumentów.

script, jak wskazuje nazwa, pozwala wykorzystywać skrypty w zapytaniach. Przydatna funkcjonalność gdy zabraknie nam czegoś w podstawowych zapytaniach Elasticsearcha.

percolate jest szczególnie ciekawe i niejako „odwraca role” – w indeksie dokumentów przechowujemy zapytania, które chcemy przetestować, a w zapytaniu percolate przesyłamy dokument sprawdzający, które z przechowywanych zapytań nam ten dokument znajdzie.

wrapper przyjmuje dowolne zapytanie zakodowane przy pomocy base64.

Zapytania typu span

Ostatnią dużą grupą zapytań dostarczanych przez Elasticsearcha są zapytania typu span. Ciężko jest mi przetłumaczyć nazwę grupy na język polski. Generalnie rzecz biorąc umożliwiają one tworzenie niskopoziomowych zapytań z uwzględnieniem położenia zadanych wyrażeń wewnątrz dokumentów. W większości przypadków nie wymagamy od wyszukiwarek precyzyjnego określenia, w który miejscu dokumentu znajduje się wyrażenie „Robb Stark”, a w którym „Jon Snow” i jak daleko od siebie leżą. Kiedy jednak mamy taką konieczność, to z pomocą przychodzą właśnie zapytania typu span. Dokumentacja Elasticsearcha jako przykład przywołuje tu przeszukiwanie dokumentów prawnych lub patentów.

The End

Jak widzisz Elasticsearch dostarcza bardzo szeroki wachlarz różnego rodzaju zapytań. Nie tylko tych pełnotekstowych. Dzięki temu możemy ogarnąć znakomitą większość przypadków, a kiedy nie jesteśmy w stanie tego zrobić zawsze możemy posiłkować się składaniem zapytań, użyciem skryptu lub innej złożonej funkcjonalności.

Bądź na bieżąco!

Podobają Ci się treści publikowane na moim blogu? Nie chcesz niczego pominąć? Zachęcam Cię do subskrybowania kanału RSS, polubienia fanpage na Facebooku, zapisania się na listę mailingową:




Uwaga! Jeżeli w ciągu 24-godzin od zapisania się na listę mailingową nie otrzymasz wybranego przez siebie prezentu to skontaktuj się ze mną.

Zgoda? Zapisując się do newslettera wyrażasz zgodę na przesyłanie Ci starannie wyselekcjonowanych informacji marketingowych. Powyższe dane są przechowywane w systemie MailChimp i nie są udostępniane nikomu więcej.

lub śledzenia mnie na Twitterze. Generalnie polecam wykonanie wszystkich tych czynności, bo często zdarza się tak, że daną treść wrzucam tylko w jedno miejsce. Zawsze możesz zrobić to na próbę, a jeśli Ci się nie spodoba – zrezygnować :)

Dołącz do grup na Facebooku

Chcesz więcej? W takim razie zapraszam Cię do dołączenia do powiązanych grup na Facebooku, gdzie znajdziesz dodatkowe informacje na poruszane tutaj tematy, możesz podzielić się własnymi doświadczeniami i przemyśleniami, a przede wszystkim poznasz ludzi interesujących się tą samą tematyką co Ty.

W grupie Programista Na Swoim znajdziesz wiele doświadczonych osób chętnych do porozmawiania na tematy krążące wokół samozatrudnienia i prowadzenia programistycznej działalności gospodarczej. Vademecum Juniora przeznaczone jest zaś do wymiany wiedzy i doświadczeń na temat życia, kariery i problemów (niekoniecznie młodego) programisty.

Wesprzyj mnie

Jeżeli znalezione tutaj treści sprawiły, że masz ochotę wesprzeć moją działalność online, to zobacz na ile różnych sposobów możesz to zrobić. Niezależnie od tego co wybierzesz, będę Ci za to ogromnie wdzięczny.

Na wsparciu możesz także samemu zyskać. Wystarczy, że rzucisz okiem na listę różnych narzędzi, które używam i polecam. Decydując się na skorzystanie z któregokolwiek linku referencyjnego otrzymasz bonus również dla siebie.

Picture Credits
Tribute to Patrons