Zrozumienie Elasticsearch Query DSL

Nie tylko kopiuj-wklej ze Stack Overflow, ale zrozumienie, co kopiujesz-wklejasz.

Elasticsearch jest obecnie najpopularniejszą wyszukiwarką, ale jego Query DSL wymaga stromej krzywej uczenia się. Kiedy po raz pierwszy zacząłem pisać zapytania do Elasticsearcha, udało mi się sklecić coś, co działało dzięki połączeniu dokumentów Elastic.co i Stack Overflow, ale nie rozumiałem w pełni podstawowych pojęć stojących za składnią.

Tutorial ten ma być tym, co chciałbym przeczytać na początku. Zakłada on, że czytelnik zna podstawowe pojęcia związane z Elasticsearch, potrafi pisać proste zapytania i rozumie logikę boolean. Ma on na celu zapewnienie czytelnikowi solidnych podstaw koncepcyjnych Elasticsearch przed próbą zrozumienia składni.

Filtrowanie po dokładnych wartościach vs Wyszukiwanie pełnotekstowe

Nadrzędnym tematem w Elasticsearch jest to, że wszystkie zapytania można podzielić na trzy typy:

1. Filtrowanie po dokładnych wartościach
2. Wyszukiwanie po analizowanym tekście
3. Kombinacja obu

Każde pole dokumentu może być sklasyfikowane albo jako dokładne wartości albo analizowany tekst (zwany również pełnym tekstem). Dokładne wartości to pola takie jak user_iddateemail_addresses, itp. Analizowany tekst to dane tekstowe, takie jak product_description lub email_body. Jak sama nazwa wskazuje, te dane tekstowe zostały przeanalizowane (więcej na ten temat później). Często jest to język naturalny, ale niekoniecznie.

Pytanie o dokumenty może odbywać się poprzez określanie filtrów na dokładnych wartościach. W takich przypadkach pytanie o to, czy dokument zostanie zwrócony jest binarnym tak lub nie. Na przykład, czy user_id jest równy 174517 ? Czy data dokumentu created_at mieści się w zakresie ostatniego miesiąca?

Z drugiej strony, zapytanie do dokumentów poprzez przeszukiwanie analizowanego tekstu zwraca wyniki oparte na trafności. Dokument nie jest zwracany na podstawie kryteriów tak/nie, ale na podstawie tego, jak bardzo jest on istotny. Na przykład, jeśli analizowany tekst dokumentu zawiera Johnny’ego Deppa, powinien on również zostać zwrócony przy wyszukiwaniu John Depp lub Johnnie Depp. Wyszukiwanie dla cook powinno również zwrócić wyniki dla cooking i cooked.

Z tego zachowania można wywnioskować, że wyszukiwanie według analizowanego tekstu jest bardzo złożoną operacją i wymaga różnych pakietów analizatorów w zależności od typu danych tekstowych. Na przykład, niektóre pakiety analizatorów są specyficzne dla danego języka, które są używane do analizy tekstu w danym języku. Domyślnym pakietem analizatora jest standardowy analizator, który dzieli tekst według granic słów, małych liter i usuwa interpunkcję. Ponieważ wyszukiwanie po przeanalizowanym tekście jest o wiele bardziej skomplikowane niż filtrowanie po dokładnych wartościach, jest ono o wiele mniej wydajne niż filtrowanie po dokładnych wartościach. W skrócie, wyszukiwanie przez analizowany tekst będziemy nazywać wyszukiwaniem analizowanym.

The Query DSL

Kwerendy Elasticsearch składają się z jednej lub wielu klauzul zapytania. Klauzule zapytań mogą być łączone w celu utworzenia innych klauzul zapytań, zwanych złożonymi klauzulami zapytań. Wszystkie klauzule zapytań mają jeden z dwóch formatów:

{
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}{
QUERY_CLAUSE: {
FIELD_NAME: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}

Zasadą składni jest, że klauzule zapytań mogą być wielokrotnie zagnieżdżane wewnątrz innych klauzul zapytań

{
QUERY_CLAUSE {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
QUERY_CLAUSE: {
ARGUMENT: VALUE,
ARGUMENT: VALUE,...
}
}
}
}
}

Przykładowe klauzule zapytań.

Klauzula zapytania match

Klauzula zapytania match jest najbardziej ogólną i najczęściej używaną klauzulą zapytania. Jest ona dość inteligentna w tym sensie, że kiedy jest uruchamiana na analizowanym polu tekstowym, wykonuje analizowane wyszukiwanie na tekście. Kiedy jest uruchamiana na polu o dokładnej wartości, wykonuje filtr.

W poniższym przykładzie, pierwsza klauzula zapytania wykona analizowane wyszukiwanie, ponieważ description jest analizowanym polem tekstowym. Natomiast 2 drugie zapytania są filtrami nad polami o dokładnej wartości.

{ "match": { "description": "Fourier analysis signals processing" }}
{ "match": { "date": "2014-09-01" }}
{ "match": { "visible": true }}

Klauzula zapytania Match All

Klauzula zapytania match all zwraca wszystkie dokumenty. Jest to analogiczne do SELECT * FROM table w SQL.

{ "match_all": {} }

Klauzula zapytania term/Terms

Klauzule zapytania term i terms służą do filtrowania po polach z dokładną wartością, odpowiednio po pojedynczych lub wielu wartościach. W przypadku wielu wartości, logicznym połączeniem jest OR .

Na przykład, pierwsze zapytanie znajduje wszystkie dokumenty z tagiem „math”. Drugie zapytanie znajdzie wszystkie dokumenty z tagami „math” lub „statistics”.

{ "term": { "tag": "math" }}
{ "terms": { "tag": }}

Klauzula zapytania multi match

Klauzula zapytania multi match to zapytanie dopasowujące, które jest uruchamiane na wielu polach zamiast tylko na jednym.

{
"multi_match": {
"query": "probability theory",
"fields":
}
}

Filtry Exists i Missing Filters

Filtr exists sprawdza, czy dokumenty posiadają wartość w określonym polu. Filtr brakujący sprawdza, czy dokumenty nie mają wartości w określonym polu. Są one analogiczne do klauzul SQL IS NULL i IS NOT NULL.

{
"exists" : {
"field" : "title"
}
}

i

{
"missing" : {
"field" : "title"
}
}

Klauzula zapytania filtru zakresu

Klauzula zapytania filtru zakresu służy do filtrowania pól liczb i dat w zakresach, przy użyciu operatorów gtgteltlte skrót od greater_thangreater_than_or_equalless_than i less_than_or_equal , odpowiednio.

{ "range" : { "age" : { "gt" : 30 } } }{ 
"range": {
"born" : {
"gte": "01/01/2012",
"lte": "2013",
"format": "dd/MM/yyyy||yyyy"
}
}
}

Bool Query Clause

Klauzule zapytań, które są zbudowane z innych klauzul zapytań są nazywane złożonymi klauzulami zapytań. Zauważ, że złożone klauzule zapytań mogą być również złożone z innych złożonych klauzul zapytań, co pozwala na wielowarstwowe zagnieżdżanie.

Klauzula bool jest przykładem złożonej klauzuli zapytań, ponieważ jest używana do łączenia wielu klauzul zapytań przy użyciu operatorów boolean. Trzy obsługiwane operatory boolean to mustmust_not oraz should , które odpowiadają odpowiednio ANDNOT , i OR ,.

Na przykład załóżmy, że mamy indeks na stronie posts popularnego serwisu społecznościowego. Oto zapytanie, które ma na celu znalezienie wszystkich posts o matematyce, które nie są prawdopodobieństwem, gdzie są albo nieprzeczytane, albo zostały przychylone.

{
"bool": {
"must": { "term": { "tag": "math" }},
"must_not": { "term": { "tag": "probability" }},
"should":
}
}

Połączenie wyszukiwania analizowanego z filtrami

Mówiliśmy o filtrach dokładnego pola i wyszukiwaniu analizowanym w oddzielnych kontekstach, ale w rzeczywistych zastosowaniach często chcemy połączyć te dwa elementy. Łączymy analizowane wyszukiwanie i dokładne filtry pól używając klauzuli filtered.

Na przykład, załóżmy, że mamy indeks na posts popularnego forum internetowego o matematyce. Oto zapytanie, które ma na celu odnalezienie wszystkich postów poprzez wykonanie analizy wyszukiwania dla „Teorii Prawdopodobieństwa”, ale chcemy tylko posts z 20 lub więcej upvotes, a nie tych z tagiem „frequentist”.

{
"filtered": {
"query": { "match": { "body": "Probability Theory" }},
"filter": {
"bool": {
"must": {
"range": { "upvotes" : { "gt" : 20 } }
},
"must_not": { "term": { "tag": "frequentist" } }
}
}
}
}

Podsumowanie

Koncepcyjne tło Elasticsearch query DSL to dychotomia filtrowania dokumentów vs przeszukiwania analizowanego tekstu. Mam nadzieję, że to się komuś przyda.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *