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