Elasticsearch podstawowe operacje

Co mogę zrobić z Elasticsearch?

Zakładam, że wiesz, czym jest Elasticsearch:
https://jaroslawstadnicki.pl/2024/03/12/co-to-jest-elasticsearch/
Oraz że wiesz, jak go uruchomić:
https://jaroslawstadnicki.pl/2024/03/04/elasticsearch-i-docker/

Jak zacząć z tym pracować?

Zacznijmy od sprawdzenia, czy działa ping! Taki hello world dla Elasticsearch:

GET: http://localhost:9200

❗❗❗ W zależności od konfiguracji używaj http lub https

Jeśli świat nie zechce inaczej, to w wyniku powinno pokazać się
You know, for search

{
“name”: “22e9589dd825”,
“cluster_name”: “docker-cluster”,
“cluster_uuid”: “jUlehFZgRO-ibt6m5VKx6Q”,
“version”: {
“number”: “8.12.0”,
“build_flavor”: “default”,
“build_type”: “docker”,
“build_hash”: “1665f706fd9354802c02146c1e6b5c0fbcddfbc9”,
“build_date”: “2024-01-11T10:05:27.953830042Z”,
“build_snapshot”: false,
“lucene_version”: “9.9.1”,
“minimum_wire_compatibility_version”: “7.17.0”,
“minimum_index_compatibility_version”: “7.0.0”
},
“tagline”: “You Know, for Search
}

Gdzie baza?

Skoro to działa, to co mogę dalej? Gdzie bazy danych? Albo indeksy? Skoro to Elasticsearch;

GET: http://localhost:9200/_cat/indices?v

U mnie pojawia się taki pusty zapis:

health status index uuid pri rep docs.count docs.deleted store.size pri.store.size dataset.size

Bo specjalnie dla Ciebie, usunąłem swój indeks i pokazuje co i jak wygląda na początku świata. Nie mam bazy danych i jak z tym żyć? Prościzna, wystarczy jeden strzał i już będzie:

PUT: http://localhost:9200/courses

(Tak, uwaga, tutaj jest PUT, sprawdź sam co odpowie Elasticsearch gdy zaproponujesz POSTa), w poprawnej odpowiedzi otrzymuje potwierdzenie:

{
    “acknowledged”: true,
    “shards_acknowledged”: true,
    “index”: “courses
}
Następnie ponownie zrobię pobranie indeksów:
GET: http://localhost:9200/_cat/indices?v
Będzie skutkowało teraz taką informacją:
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size dataset.size
yellow open courses _JyXbuNdSlqPymuUQDL5tg 1 1 0 0 227b 227b 227b
Polecam robić to u lokalnie, formatowanie nie jest przyjazne dla długich linijek.
Usunięcie bazy, to prosty strzał:
DEL: http://localhost:9200/courses z odpowiedzią
Wynik:
{
    “acknowledged”: true
}
Odtworzę (PUT: http://localhost:9200/courses) indeks i mogę działać
ponownie.

Gdzie dane

Mam miejsce, gdzie mogę trzymać dane, to jak je tam teraz załadować? Czy to proste? Jak pisanie tego posta!
Wystarczy wykonać
POST: http://localhost:9200/courses/_doc

U mnie body wygląda w ten sposób:

{
    “name“: “elasticsearch i docker”,
    “description“: “Elasticsearch Jest to pierwszy z cyklu wpisów o Elasticsearch, opracowane na podstawie oficjalnej dokumentacji dostępnej pod linkiem: https://www.elastic.co/guide/en/elasticsearch/reference/8.12/docker.html W prywatnym projekcie, nad którym pracuje, do wyszukiwania kursów będę korzystać  narzędzia Elasticsearch. Ponieważ potrzebuje lepiej poznać to narzędzie, postanowiłem udokumentować kilka kroków z mojej podróży, aby dzielić się wiedzą, a jednocześnie liczę, że przyda się to także innym. Zamierzam korzystać z instalacji opartej o Docker i poniży wpis jest właśnie taką uproszczoną instrukcją jak tego dokonać.”
}

Dla lepszego efektu wykonam jeszcze jedną operację z takim body na ten sam url jak poprzednio:

{
    “name“: “co to jest elasticsearch”,
    “description“: “Czym jest elasticsearch? Sam elastisearch reklamuje się tym sloganem: You know, for search (and analysis) I generalnie tak jest, gdy myślę o szukaniu danych (wydajnym) to na myśl przychodzi mi właśnie Elasticsearch. Ale czekaj, bo to nie tylko szukanie – to znaczy i tak i nie, bo Elastic to coś więcej niż search, jest tam także Kibana, która ułatwia przeglądanie tego co mamy w bazie czy Logstash do wrzucania logów do tejże bazy. Ja, póki co skupiam się na Elasticsearch jako silniku do szukania, oprócz szukania potrafi też podać dodatkowe informacje dotyczące wyników; agregacje, statystyki, czy wyniki bliskie do tych, które są dla nas interesujące..”
}
Wyniki takich operacji wyglądają jakoś tak:
{
    “_index”: “courses”,
    “_id”: “QOTVb44BFw2yxe2y3POW”,
    “_version”: 1,
    “result”: “created”,
    “_shards”: {
        “total”: 2,
        “successful”: 1,
        “failed”: 0
    },
    “_seq_no”: 0,
    “_primary_term”: 1
}
Sprawdzam, czy są:
GET: http://localhost:9200/courses/_count
Czary:
{
    “count”: 2,
    “_shards”: {
        “total”: 1,
        “successful”: 1,
        “skipped”: 0,
        “failed”: 0
    }
}

Poka dane

Wygląda, że się zgadza! , gdzie szukanie? Selekt gwiazdka from students!
GET: http://localhost:9200/courses/_search
Muszę się ratować gistem, także:

Taki search “szuka” wszystkiego, co jest, można to ograniczać i zawężać wyniki, np:

http://localhost:9200/courses/_search?size=1&from=1

Ale gdyby tak poszukać czegoś konkretnego, warto wrzucić coś do body takiego zapytania, także robimy:
GET: http://localhost:9200/courses/_search

Z body ustawionym w taki sposób:

{
    “query”: {
        “simple_query_string”: {
            “query”: “co to jest elasticsearch”
        }
    }
}

Zwróci oba dokumenty, gdzie ten z takim właśnie tytułem będzie jako pierwszy, natomiast podmiana tego query na “elasticsearch i docker” – zmieni kolejnośc wyników – zwróć uwagę na pola:”max_score“: 3.9204745, oraz “_score“: 3.9204745 czy “_score“: 1.0661358. Warto także wrzucić w query to, co jest w opisie i zobaczyć czy szukanie też będzie działać – 🧝‍♂️

WHERE

Gdybyś chciał zawęzić pole wyszukiwania tylko do np. nazwy posta, można to zrobić modyfikując body w taki sposób:

{
    “query”: {
        “simple_query_string”: {
            “query”: “docker”,
            “fields“:[“name”]
        }
    }
}
Co spowoduje, że szukać będzie w name i nie zwróci już obu wyników.

Group by

Na koniec jeszcze grupowanie, bo to jest bardzo przydatna opcja. Aby lepiej pokazać wyniki dodałem, jeden dokument z takim samym tytułem — i jakimś krótkim opisem, a dodatkowo wyłączyłem szukanie, na potrzeby przejrzystego wyniku agregacji:

GET: http://localhost:9200/courses/_search

Body:
{
    “size”:0,
    “aggs”:{
        “names”:{
            “terms”:{
                “field”:”name.keyword”,
                “size”:10
            }
        }
    }
}
Rezultat:
Wynik zawiera informacje o agregowaniu na podstawie nazwy — co daje dwa dokumenty dla “elasticsearch i docker” (jeden, specjalnie dodany) oraz jeden dla “co to jest elasticsearch”.
Jeśli włączyć do tego wyszukiwanie, to agregowanie danych zostanie wykonane tylko na wynikach pasujących do zapytania:
{
    “size“:0,
    “query“: {
        “simple_query_string”: {
            “query”: “docker”,
            “fields”:[“name”]
        }
    },
    “aggs”:{
        “names”:{
            “terms”:{
                “field”:”name.keyword”,
                “size”:10
            }
        }
    }
}
W wypadku w agregacji dostanę tylko informacje o pasujących dokumentach, ale sam dokument nie zostanie wyświetlony — ponownie użyłem “size:0″.

Optymalizacja i selekcja danych

Na koniec jeszcze optymalizacja wyników, nie trzeba / nie powinno się ciągnąć pełnego dokumentu, dlatego można zawęzić się tylko do interesujących pól:
{
    “query”: {
        “simple_query_string”: {
            “query”: “docker”,
            “fields”:[“name”]
        }
    },
    “fields”:[“name”],
    “_source”:false
}
Zwróć uwagę na dodatkowe pole _source – sprawdź różnice w wynikach gdy usuniesz ten atrybut z body zapytania.
Od teraz potrafisz, tworzyć i usuwać bazy w elasticsearch, dodawać oraz szukać danych w swojej bazie opartej o Elasticsearch

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.