{"id":25430,"date":"2023-11-08T05:00:00","date_gmt":"2023-11-08T04:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=25430"},"modified":"2023-11-06T14:34:12","modified_gmt":"2023-11-06T13:34:12","slug":"poznaj-elasticsearch-narzedzie-do-przeszukiwania-i-analizy-danych","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/poznaj-elasticsearch-narzedzie-do-przeszukiwania-i-analizy-danych\/","title":{"rendered":"Poznaj Elasticsearch \u2013 narz\u0119dzie do przeszukiwania i analizy danych"},"content":{"rendered":"\n<p>Elasticsearch to rozproszony silnik do przeszukiwania i analizy danych, oparty na bibliotece Apache Lucene (biblioteka do indeksowania i wyszukiwania, licencja Apache License 2.0). Z tego powodu jest cz\u0119sto por\u00f3wnywany do podobnego rozwi\u0105zania, jakim jest Apache Solr. <\/p>\n\n\n\n<p>Elasticsearch jest napisany w Javie, a jego pierwsza wersja ukaza\u0142a si\u0119 w roku 2010. Jej autorem by\u0142 Shay Banon. Aktualnie rozwojem zajmuje si\u0119 firma Elastic NV, a najnowsz\u0105 stabiln\u0105 wersj\u0105 na dzie\u0144 dzisiejszy jest 8.9.1, kt\u00f3ra zosta\u0142a wydana 14 sierpnia 2023 roku. Rozwi\u0105zanie przybli\u017c\u0119 w niniejszym artykule.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Mo\u017cliwo\u015bci<\/strong><\/h2>\n\n\n\n<p>Elasticsearch to narz\u0119dzie, kt\u00f3re oferuje szereg funkcji umo\u017cliwiaj\u0105cych przeszukiwanie i analiz\u0119 danych w spos\u00f3b efektywny i wszechstronny. Poni\u017cej kluczowe mo\u017cliwo\u015bci, jakie oferuje Elasticsearch:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Zbieranie i analiza log\u00f3w:<\/strong> Logi generowane przez aplikacje cz\u0119sto s\u0105 rozproszone w r\u00f3\u017cnych cz\u0119\u015bciach infrastruktury i zawieraj\u0105 dane w wielu formatach. Elasticsearch daje mo\u017cliwo\u015b\u0107 \u0142atwego scentralizowania tych danych, a nast\u0119pnie ich analizy oraz wizualizacji.<\/li>\n\n\n\n<li><strong>Wyszukiwanie pe\u0142notekstowe:<\/strong> Elasticsearch oferuje wiele r\u00f3\u017cnych rodzaj\u00f3w zapyta\u0144, takie jak match, match phrase, range, fuzzy, autocompletery i wiele innych.<\/li>\n\n\n\n<li><strong>Enterprise search:<\/strong> Umo\u017cliwia tworzenie aplikacji do wyszukiwania danych na podstawie indeks\u00f3w Elasticsearcha, ale dodatkowo \u2013 i to stanowi o potencjale tego rozwi\u0105zania \u2013 r\u00f3wnie\u017c z innych \u017ar\u00f3de\u0142. Udost\u0119pnione s\u0105 narz\u0119dzia, takie jak web crawler do indeksowania zawarto\u015bci z HTML, konektory do popularnych baz danych i aplikacji (MySQL, PostgreSQL, MongoDB, Jira) oraz wiele innych connector\u00f3w do \u017ar\u00f3de\u0142 danych.<\/li>\n\n\n\n<li><strong>Analiza w czasie rzeczywistym:<\/strong> Elasticsearch umo\u017cliwia analiz\u0119 w czasie rzeczywistym danych zebranych z r\u00f3\u017cnych \u017ar\u00f3de\u0142, takich jak logi systemowe, metryki, dane ze zdalnych sensor\u00f3w czy urz\u0105dze\u0144 IoT. Przetworzone dane mo\u017cna nast\u0119pnie prezentowa\u0107 w Kibanie lub tworzy\u0107 alerty.<\/li>\n\n\n\n<li><strong>Analiza danych geoprzestrzennych:<\/strong> Elasticsearch umo\u017cliwia analiz\u0119 danych geoprzestrzennych, przechowuj\u0105c dane geograficzne jako punkt (geo_point) lub kszta\u0142t (geo_shape). W tym drugim przypadku mamy mo\u017cliwo\u015b\u0107 u\u017cycia wielu r\u00f3\u017cnych typ\u00f3w, np. Point, Line, Polygon, kolekcje powy\u017cszych i inne. Dost\u0119pne s\u0105 r\u00f3wnie\u017c r\u00f3\u017cne zapytania geoprzestrzenne (geo queries), kt\u00f3re pozwalaj\u0105 na wykonywanie operacji od pomiaru odleg\u0142o\u015bci mi\u0119dzy punktami po bardziej zaawansowane, takie jak sprawdzenie czy dwa obiekty typu geo_shape maj\u0105 cz\u0119\u015b\u0107 wsp\u00f3ln\u0105. Takie dane mo\u017cemy umieszcza\u0107 jako warstwy na mapie i u\u017cywa\u0107 w dashboardach stworzonych w Kibanie.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Elasticsearch jako zbi\u00f3r aplikacji<\/strong><\/h2>\n\n\n\n<p>Elasticsearch jest tak naprawd\u0119 zbiorem aplikacji pod wsp\u00f3ln\u0105 nazw\u0105 \u201e<strong>Elastic Stack<\/strong>\u201d (wcze\u015bniej \u201eELK stack\u201d, skr\u00f3t od \u201eElasticsearch, Logstash, Kibana\u201d).<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack.png\"><img decoding=\"async\" width=\"1024\" height=\"363\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-1024x363.png\" alt=\"Aplikacje wchodz\u0105ce w sk\u0142ad Elastic Stack\" class=\"wp-image-25432\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-1024x363.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-300x106.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-768x272.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-1536x545.png 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elk_stack-2048x726.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 1 <a href=\"https:\/\/www.elastic.co\/\" target=\"_blank\" aria-label=\"Aplikacje wchodz\u0105ce w sk\u0142ad Elastic Stack (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Aplikacje wchodz\u0105ce w sk\u0142ad Elastic Stack<\/a><\/figcaption><\/figure>\n\n\n\n<p>W sk\u0142ad Elastic Stack, opr\u00f3cz samego Elastricsearch, wchodz\u0105:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Logstash<\/strong> \u2013 silniki do gromadzenia danych i analizowania log\u00f3w.<\/li>\n\n\n\n<li><strong>Kibana<\/strong> \u2013 narz\u0119dzie umo\u017cliwiaj\u0105ce podgl\u0105d i wizualizacj\u0119 danych zawartych w Elastisearchu oraz monitorowanie i zarz\u0105dzanie ca\u0142ym stackiem.<\/li>\n\n\n\n<li><strong>Beats<\/strong> \u2013 zestaw narz\u0119dzi u\u0142atwiaj\u0105cych dodawanie danych do Elasticsearch. Przyk\u0142adowo mamy tutaj:<ul><li>Filebeat \u2013 dodawania log\u00f3w,<\/li><\/ul><ul><li>Metricbeat \u2013 dodawanie metryk,<\/li><\/ul><ul><li>Packetbeat \u2013 dodawanie danych sieciowych,<\/li><\/ul><ul><li>Winlogbeat \u2013 dodawanie log\u00f3w w eventami systemu windows,<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>i inne.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Wi\u0119cej informacji o Elastic Stack mo\u017cecie znale\u017a\u0107 <a href=\"https:\/\/www.elastic.co\/elastic-stack\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >na stronie rozwi\u0105zania<\/a>.<\/p>\n\n\n\n<p>Elasticsearch udost\u0119pnia REST-owe API, dzi\u0119ki kt\u00f3rym mo\u017cemy zarz\u0105dza\u0107 klastrem, indeksowa\u0107 dokumenty i przeprowadza\u0107 operacje wyszukiwania i wiele innych. Szczeg\u00f3\u0142owa lista jest dost\u0119pna <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/rest-apis.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>. API domy\u015blnie wystawione jest na porcie 9200.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>OpenSearch<\/strong><\/h2>\n\n\n\n<p>W roku 2021 licencja Elasticsearch zosta\u0142a zmieniona z otwartej licencji Apache License na Server Side Public License. Licencja SSPL nie jest uznawana za w pe\u0142ni otwart\u0105 przez wiele stron, w tym Open Source Initiative (OSI) oraz tw\u00f3rc\u00f3w wielu wersji systemu Linux. Z tego te\u017c powodu Amazon postanowi\u0142 stworzy\u0107 otwart\u0105 wersj\u0119 Elasticsearch, kt\u00f3ra powsta\u0142a w 2021r jako fork wersji 7.10.2 i jest rozwijana pod licencj\u0105 Apache License 2 przez AWS. Najnowsza stabilna wersja, dost\u0119pna na dzie\u0144 dzisiejszy, to 2.9.0 z 24 lipca 2023 roku.<\/p>\n\n\n\n<p>Znakomita wi\u0119kszo\u015b\u0107 funkcji zwi\u0105zanych z wyszukiwaniem, analiz\u0105 i prezentacj\u0105 danych jest w obu rozwi\u0105zaniach identyczna. Oczywi\u015bcie jest te\u017c kilka znacz\u0105cych r\u00f3\u017cnic. Ze wzgl\u0119du na to, \u017ce Opensearch jest oprogramowaniem open source, ma bardziej liberaln\u0105 licencj\u0119, ale nie oferuje oficjalnego wsparcia dla wdro\u017cenia oprogramowania.<\/p>\n\n\n\n<p>Elasticsearch posiada wi\u0119ksz\u0105 gam\u0119 bibliotek umo\u017cliwiaj\u0105cych integracj\u0119 z r\u00f3\u017cnymi j\u0119zykami oprogramowania, podczas gdy dla Opensearch jest ona bardziej uboga i implementacja mo\u017ce by\u0107 bardziej problematyczna. Najnowsze wersje narz\u0119dzi, takich jak Logstash czy Beats, nie dzia\u0142aj\u0105 z Opensearchem. W odpowiedzi na ten problem powsta\u0142o narz\u0119dzie Data Prepper, niestety na ten moment nie oferuje ono jeszcze takich mo\u017cliwo\u015bci jak konkurencja. <\/p>\n\n\n\n<p>Oba systemy oferuj\u0105 mo\u017cliwo\u015b\u0107 uwierzytelniania za pomoc\u0105 LDAP, OpenID czy SAML. W Opensearch dostajemy to w standardzie, a w przypadku Elasticsearch tylko w p\u0142atnych licencjach. To samo tyczy si\u0119 takich funkcjonalno\u015bci jak IP filtering czy autoryzacja na poziomie dokument\u00f3w lub nawet na poziomie poszczeg\u00f3lnych p\u00f3l w dokumentach. Je\u015bli chodzi o wydajno\u015b\u0107, ci\u0119\u017cko znale\u017a\u0107 wiarygodne benchmarki. Na stronach elastic.co mo\u017cna znale\u017a\u0107 wyniki test\u00f3w przeprowadzonych przez nich samych, a poni\u017csza grafika podsumowuje te wyniki:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch.jpg\"><img decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-1024x576.jpg\" alt=\"Wyniki test\u00f3w wydajno\u015bciowych\" class=\"wp-image-25434\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-1024x576.jpg 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-300x169.jpg 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-768x432.jpg 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-1536x864.jpg 1536w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-555x312.jpg 555w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch-1920x1080.jpg 1920w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/elasticsearch_vs_opensearch.jpg 1999w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 2 <a href=\"https:\/\/www.elastic.co\/blog\/elasticsearch-opensearch-performance-gap\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Wyniki test\u00f3w wydajno\u015bciowych<\/a><\/figcaption><\/figure>\n\n\n\n<p>Na stronie <a href=\"https:\/\/www.elastic.co\/blog\/elasticsearch-opensearch-performance-gap\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >Elastic.co<\/a> mo\u017cna znale\u017a\u0107 metodologi\u0119 test\u00f3w i informacj\u0119 o walidacji wynik\u00f3w przez niezale\u017cnych ekspert\u00f3w. Jednak, bior\u0105c pod uwag\u0119, \u017ce wyniki zosta\u0142y opublikowane na stronie jednej z zainteresowanych firm, warto podej\u015b\u0107 do nich z pewnym dystansem. Strona projektu Opensearch dost\u0119pna jest <a href=\"https:\/\/opensearch.org\/\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Dane<\/strong><\/h2>\n\n\n\n<p>W Elasticsearch dane s\u0105 reprezentowane w postaci dokument\u00f3w. W przeciwie\u0144stwie do przechowywania informacji w wierszach tabel, jak ma to miejsce w relacyjnych bazach danych, <strong>Elasticsearch przechowuje dane jako z\u0142o\u017cone struktury w formie zserializowanych dokument\u00f3w JSON<\/strong>. Je\u015bli w klastrze znajduje si\u0119 wiele w\u0119z\u0142\u00f3w Elasticsearch (a taka jest idea systemu rozproszonego!),\u00a0dokumenty s\u0105 rozproszone po ca\u0142ym klastrze, co umo\u017cliwia natychmiastowy dost\u0119p do nich z dowolnego w\u0119z\u0142a.<\/p>\n\n\n\n<p>Zapisany dokument zostaje zindeksowany (dodany) i jest dost\u0119pny do wyszukiwania niemal w czasie rzeczywistym. Podczas procesu indeksowania ka\u017cdy dokument otrzymuje sw\u00f3j unikatowy identyfikator. Elasticsearch chwali si\u0119, \u017ce proces trwa oko\u0142o sekundy, co jest bardzo prawdopodobne.<\/p>\n\n\n\n<p>Dokumenty s\u0105 organizowane w indeksy, kt\u00f3re stanowi\u0105 logiczne kontenery dla dokument\u00f3w o podobnej strukturze. Mo\u017cemy o nim my\u015ble\u0107 jak o odpowiedniku tabeli w klasycznej bazie danych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Skalowalno\u015b\u0107 systemu i bezpiecze\u0144stwo danych<\/strong><\/h2>\n\n\n\n<p>Elasticsearch zosta\u0142 stworzony z my\u015bl\u0105 o skalowalno\u015bci i niezawodno\u015bci. Aby zwi\u0119kszy\u0107 dost\u0119pne zasoby, wystarczy doda\u0107 kolejny w\u0119ze\u0142 (node) do klastra. Elasticsearch automatycznie rozdzieli obci\u0105\u017cenie danymi i zapytaniami pomi\u0119dzy wszystkie dost\u0119pne w\u0119z\u0142y.<\/p>\n\n\n\n<p>Indeks w Elasticsearch jest w\u0142a\u015bciwie elementem logicznym. Ka\u017cdy indeks jest podzielony na shardy, czyli fizyczne fragmenty danych. Shardy umo\u017cliwiaj\u0105 r\u00f3wnoleg\u0142e przetwarzanie i przechowywanie danych. Przy tworzeniu indeksu mo\u017cna okre\u015bli\u0107 liczb\u0119 shard\u00f3w, kt\u00f3re zostan\u0105 u\u017cyte, co wp\u0142ywa na r\u00f3wnomierno\u015b\u0107 obci\u0105\u017cenia i wydajno\u015b\u0107. Najcz\u0119\u015bciej liczb\u0119 shard\u00f3w ustawia si\u0119 na warto\u015b\u0107 r\u00f3wn\u0105 ilo\u015bci nod\u00f3w. Dzi\u0119ki temu dane zostan\u0105 r\u00f3wnomiernie rozproszone pomi\u0119dzy wszystkie dost\u0119pne w\u0119z\u0142y.<\/p>\n\n\n\n<p>Ale co nam to daje? Za\u0142\u00f3\u017cmy, \u017ce nasz indeks zawiera 1 mln rekord\u00f3w. Gdy umie\u015bcimy je w jednym shardzie (na jednym nodzie), to wyszukanie interesuj\u0105cego nas rekordu zajmuje 10 sekund. Teraz za\u0142\u00f3\u017cmy, \u017ce tworzymy 10 w\u0119z\u0142\u00f3w i dzielimy indeks na 10 shard\u00f3w. W\u00f3wczas mo\u017cemy wyszukiwa\u0107 na ka\u017cdym shardzie r\u00f3wnocze\u015bnie. Teoretycznie czas wyszukiwania skr\u00f3ci si\u0119 do 1 sekundy. Oczywi\u015bcie w praktyce trzeba doda\u0107 niewielki narzut zwi\u0105zany z koordynacj\u0105 zapyta\u0144 i komunikacj\u0105 mi\u0119dzy nodami, ale i tak przyrost pr\u0119dko\u015bci jest ogromny.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Algorytm deterministyczny<\/strong><\/h2>\n\n\n\n<p>Elasticsearch na podstawie identyfikatora dokumentu sam routuje go do odpowiedniego shardu i jest to oczywi\u015bcie algorytm deterministyczny. Sam algorytm wygl\u0105da nast\u0119puj\u0105co:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">shard_num = (hash(_routing) % num_routing_shards) \/ routing_factor<\/pre>\n\n\n\n<p>Gdzie:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">routing_factor = num_routing_shards \/ num_primary_shards<\/pre>\n\n\n\n<p><em><code>num_routing_shards i num_primary_shards<\/code><\/em> to warto\u015bci ustawione w konfiguracji indeksu. <em><code>A _routing<\/code><\/em> to w\u0142a\u015bnie identyfikator dokumentu w Elasticsearch. <strong>Podczas wysy\u0142ania dokumentu do Elasticsearch, istnieje mo\u017cliwo\u015b\u0107 nadania w\u0142asnego klucza routingu w celu wymuszenia umieszczenia dokumentu w konkretnym shardzie.<\/strong> Jednak wtedy podczas ka\u017cdej innej operacji na dokumencie (get, delete, update) trzeba w zapytaniu wskaza\u0107 ten sam klucz routingu.<\/p>\n\n\n\n<p>Czasem co\u015b p\u00f3jdzie nie tak jak powinno i kt\u00f3ry\u015b z nod\u00f3w (a nawet kilka z nich) ulega awarii, prowadz\u0105c do utraty danych z shardu, jaki si\u0119 nie nim znajdowa\u0142. Oczywi\u015bcie, reszta klastra nadal dzia\u0142a normalnie i dane na pozosta\u0142ych w\u0119z\u0142ach pozostaj\u0105 dost\u0119pne. Jednak, co dzieje si\u0119 z danymi na w\u0119\u017ale, kt\u00f3ry uleg\u0142 awarii?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Elasticsearch natywnie obs\u0142uguj\u0119 replikacj\u0119 shard\u00f3w, co oznacza, \u017ce shardy s\u0105 kopiowane.<\/li>\n\n\n\n<li>Ka\u017cdy z g\u0142\u00f3wnych shard\u00f3w (primary shard) ma utworzon\u0105 swoj\u0105 replik\u0119 (replica shard) na innym nodzie.<\/li>\n\n\n\n<li>Domy\u015blnie tworzona jest jedna replika, ale mo\u017cna to oczywi\u015bcie konfigurowa\u0107 pod swoje w\u0142asne potrzeby.<\/li>\n\n\n\n<li>W momencie, gdy primary shard jest niedost\u0119pny, jego rol\u0119 przejmuje replika.<\/li>\n<\/ul>\n\n\n\n<p>Z mechanizmu replikowania bezpo\u015brednio wynika jeszcze jedna zaleta. <strong>Zapytania do Elasticsearch mog\u0105 by\u0107 wykonywane jednocze\u015bnie na wszystkich replikach, co dodatkowo zwi\u0119ksza wydajno\u015b\u0107<\/strong>. Aby zapewni\u0107 sp\u00f3jno\u015b\u0107 danych, wszelkie akcje, kt\u00f3re modyfikuj\u0105 dane, s\u0105 zawsze kierowane do g\u0142\u00f3wnego sharda. Tam nast\u0119puje weryfikacja poprawno\u015bci danych, a nast\u0119pnie zapis do g\u0142\u00f3wnego sharda. Nast\u0119pnie operacja zapisu jest propagowana do replik, kt\u00f3re wysy\u0142aj\u0105 potwierdzenie do g\u0142\u00f3wnego sharda.<\/p>\n\n\n\n<p>Poni\u017cszy diagram prezentuje przyk\u0142adow\u0105 konfiguracj\u0119 dla klastra z 4 nodami, 4 g\u0142\u00f3wnymi shardami i 3 replikami per shard:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-large\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop.png\"><img decoding=\"async\" width=\"1024\" height=\"588\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop-1024x588.png\" alt=\"Przyk\u0142adowa konfiguracja dla klastra z 4 nodami, 4 g\u0142\u00f3wnymi shardami i 3 replikami per shard \" class=\"wp-image-25438\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop-1024x588.png 1024w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop-300x172.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop-768x441.png 768w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/sharding_crop.png 1123w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 3 Przyk\u0142adowa konfiguracja dla klastra z 4 nodami, 4 g\u0142\u00f3wnymi shardami i 3 replikami per shard<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Snapshoty<\/strong><\/h2>\n\n\n\n<p>Elasticsearch oferuje wbudowany system backup\u00f3w w postaci snapshot\u00f3w. Snapshoty s\u0105 przechowywane poza lokalizacj\u0105 klastra, a Elasticsearch pozwala wykorzystywa\u0107 do tego celu popularne rozwi\u0105zania chmurowe, takie jak AWS S3, Google Clooud Storage, Azure i inne.<\/p>\n\n\n\n<p>Opr\u00f3cz roli backup\/restore oraz mo\u017cliwo\u015bci przenoszenia danych mi\u0119dzy klastrami za pomoc\u0105 snapshot\u00f3w, Elasticsearch oferuje dodatkowo mechanizm \u201esearchable snapshots\u201d. Jak wynika z samej nazwy, ten mechanizm s\u0142u\u017cy do przeszukiwania danych. Mechanizm ten ma zastosowanie tylko dla danych, kt\u00f3re s\u0105 rzadko u\u017cywane i pozwala na zmniejszenie miejsca zajmowanego przez dane do 50%. <\/p>\n\n\n\n<p>Nale\u017cy zaznaczy\u0107, \u017ce Elasticsearch udost\u0119pnia searchable snapshots w p\u0142atnych licencjach podczas gdy w Opensearch jest to w pe\u0142ni darmowa opcja.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Interakcje<\/strong><\/h2>\n\n\n\n<p>Jak ju\u017c wspomnia\u0142em, Elasticsearch udost\u0119pnia nam REST-owe API. Spr\u00f3bujmy zatem utworzy\u0107 pierwszy indeks o nazwie <em>accounts<\/em>. U\u017cywamy metody PUT i odpowiedniego URL. Wygl\u0105da\u0142oby to tak:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">curl -X PUT \"localhost:9200\/accounts?pretty\"<\/pre>\n\n\n\n<p>W URL podajemy nazw\u0119 indeksu oraz dodatkowy parametr <em>pretty<\/em>, aby uzyska\u0107 odpowied\u017a w bardziej czytelnej formie. W odpowiedzi dostaniemy:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n{\n &quot;acknowledged&quot; : true,\n &quot;shards_acknowledged&quot; : true,\n &quot;index&quot; : &quot;accounts&quot;\n}\n<\/pre><\/div>\n\n\n<p>W praktyce rzadko kiedy u\u017cywa si\u0119 polecenia <em>curl<\/em>. Dla komunikacji typu M2M mamy dost\u0119pnych wielu klient\u00f3w Elasticsearch, takich jak Java, JS, PHP, Go, itp. Wi\u0119cej informacji na ten temat mo\u017cnecie znale\u017a\u0107 <a aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/client\/index.html\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj.<\/a><\/p>\n\n\n\n<p>Dla developera najprostsz\u0105 metod\u0105 komunikacji z API Elasticsearch jest u\u017cycie jakiego\u015b klienta, np. Postmana lub Kibany. Kibana, w\u015br\u00f3d wielu narz\u0119dzi, oferuje Dev Tools-y, a w nich konsol\u0119 do tworzenia request\u00f3w i odczytywania respons\u00f3w. Konsola oferuje podpowiedzi i kolorowanie sk\u0142adni, formatowanie kodu i inne udogodnienia. Przyk\u0142adowe zapytanie tworz\u0105ce indeks mo\u017ce wygl\u0105da\u0107 tak:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q1.png\"><img decoding=\"async\" width=\"946\" height=\"80\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q1.png\" alt=\"Przyk\u0142adowe zapytanie tworz\u0105ce indeks\" class=\"wp-image-25440\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q1.png 946w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q1-300x25.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q1-768x65.png 768w\" sizes=\"(max-width: 946px) 100vw, 946px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 4 Przyk\u0142adowe zapytanie tworz\u0105ce indeks<\/figcaption><\/figure>\n\n\n\n<p>Dodajmy teraz pierwszy dokument do indeksu.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q2.png\"><img decoding=\"async\" width=\"904\" height=\"264\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q2.png\" alt=\"Zapytanie po dodaniu dokumentu do indeksu\" class=\"wp-image-25443\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q2.png 904w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q2-300x88.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q2-768x224.png 768w\" sizes=\"(max-width: 904px) 100vw, 904px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 5 Zapytanie po dodaniu dokumentu do indeksu<\/figcaption><\/figure>\n\n\n\n<p>Operacja si\u0119 powiod\u0142a, dokument otrzyma\u0142 identyfikator. Uwag\u0119 mo\u017ce zwr\u00f3ci\u0107 jedna rzecz. W naszym reque\u015bcie u\u017cyli\u015bmy danych o r\u00f3\u017cnych typach, mamy zmienne tekstowe, liczbowe czy dat\u0119. Nawet pojawi\u0142 si\u0119 prosty obiekt. <strong>Elasticsearch dzia\u0142a w trybie bez schematu (ang. Schema-less), co oznacza, \u017ce mo\u017ce indeksowa\u0107 dokumenty bez wyra\u017anego wskazania typu dla poszczeg\u00f3lnych p\u00f3l.<\/strong><\/p>\n\n\n\n<p>Dla nas jest to bardzo wygodne, bo umo\u017cliwia szybkie dodawanie danych bez dodatkowego narzutu pracy. Oczywi\u015bcie mamy mo\u017cliwo\u015b\u0107 utworzenia schematu danych (mapping) przed dodaniem dokumentu, co mo\u017ce by\u0107 konieczne w kilku przypadkach. Na przyk\u0142ad, gdy chcemy wymusi\u0107 konkretny tryb wyszukiwania dla danego pola (full-text albo exact value), b\u0105d\u017a gdy potrzebujemy u\u017cy\u0107 partial matching, wykona\u0107 analiz\u0119 tekstu w spos\u00f3b specyficzny dla danego j\u0119zyka, itp.<\/p>\n\n\n\n<p>Do ju\u017c istniej\u0105cego mapowania mo\u017cemy dodawa\u0107 kolejne pola, zar\u00f3wno automatycznie, jak i r\u0119cznie. Nie mo\u017cemy jednak zmieni\u0107 typu dla ju\u017c zmapowanego pola. W takim wypadku nale\u017cy usun\u0105\u0107 indeks, stworzy\u0107 nowe mapowanie i nast\u0119pnie raz jeszcze zaindeksowa\u0107 wszystkie dane.<\/p>\n\n\n\n<p>Sprawd\u017amy, jakie mapowanie stworzy\u0142 Elasticsearch dla naszych danych:<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q3.png\"><img decoding=\"async\" width=\"963\" height=\"730\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q3.png\" alt=\"Dane Elasticsearch\" class=\"wp-image-25445\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q3.png 963w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q3-300x227.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/q3-768x582.png 768w\" sizes=\"(max-width: 963px) 100vw, 963px\" \/><\/a><figcaption class=\"wp-element-caption\">Ryc. 6 Dane Elasticsearch<\/figcaption><\/figure>\n\n\n\n<p>Jak wida\u0107, Elasticsearch poradzi\u0142 sobie bardzo dobrze. Rozpozna\u0142 typy i odpowiednio ustawi\u0142 mapowania dla p\u00f3l tekstowych, liczb ca\u0142kowitych, zmiennoprzecinkowych i logicznych.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Full-text search<\/strong><\/h2>\n\n\n\n<p>Elasticsearch potrafi szybko przeprowadzi\u0107 wyszukiwania full-text. Aby zrozumie\u0107, dlaczego tak si\u0119 dzieje, warto przyjrze\u0107 si\u0119 procesowi indeksowania dokumentu.<\/p>\n\n\n\n<p>Tekst wprowadzany do Elasticsearcha jest poddawany analizie, kt\u00f3ra jest przeprowadzana przez tzw. analyzer. Istnieje wiele wbudowanych analyzer\u00f3w, mo\u017cna oczywi\u015bcie definiowa\u0107 swoje, bardziej dopasowane pod indywidualne potrzeby. Analyzer to tak naprawd\u0119 zestaw regu\u0142, kt\u00f3re zostan\u0105 u\u017cyte w procesie analizy tekstu. Zazwyczaj sk\u0142ada si\u0119 on z trzech blok\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Character filter<\/strong> \u2013 mo\u017ce wykonywa\u0107 proste operacje, takie jak usuwanie fragment\u00f3w tekstu (np. znacznik\u00f3w html), zamiany jednych znak\u00f3w na drugie, b\u0105d\u017a zamiany ci\u0105g\u00f3w znak\u00f3w pasuj\u0105cych do okre\u015blonego wyra\u017cenia regularnego. Analyzer mo\u017ce zawiera\u0107 zero lub wiele character filter\u00f3w, kt\u00f3re zostan\u0105 zastosowane w deklarowanej kolejno\u015bci. Wi\u0119cej informacji <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/analysis-charfilters.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>.<\/li>\n\n\n\n<li><strong>Tokenizer<\/strong> \u2013 dzieli podany tekst na tokeny, zazwyczaj pojedyncze s\u0142owa. Elasticsearch posiada wiele wbudowanych tokenizer\u00f3w, przy czym najcz\u0119\u015bciej u\u017cywanym jest Standard Tokenizer kt\u00f3ry dzieli tekst po znakach whitespace oraz usuwa znaki przestankowe. Analyzer musi mie\u0107 dok\u0142adnie jeden tokenizer. Wi\u0119cej informacji o tokenizerach <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/analysis-tokenizers.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>.<\/li>\n\n\n\n<li><strong>Token filter<\/strong> \u2013 wykonuje modyfikacje na otrzymanych tokenach, mo\u017ce je usuwa\u0107, dodawa\u0107 b\u0105d\u017a modyfikowa\u0107.<\/li>\n<\/ul>\n\n\n\n<p>Tak naprawd\u0119, to tutaj dzieje si\u0119 du\u017ca cz\u0119\u015b\u0107 &#8222;magii&#8221; Elasticsearcha. Oto kilka przyk\u0142adowych token filtr\u00f3w:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lowercase token filter \u2013 prosta zmiana wielkich liter na ma\u0142e.<\/li>\n\n\n\n<li>Stop token filter \u2013 usuwa tokeny (s\u0142owa), kt\u00f3re s\u0105 bez znaczenia dla procesu wyszukiwania. Elasticsearch posiada wbudowane listy stop words dla kilku j\u0119zyk\u00f3w. Oczywi\u015bcie, u\u017cytkownik mo\u017ce samodzielnie zdefiniowa\u0107 list\u0119 stop words. W przypadku j\u0119zyka angielskiego, lista wbudowanych stop words wygl\u0105da nast\u0119puj\u0105co: a, an, and, are, as, at, be, but, by, for, if, in, into, is, it, no, not, of, on, or, such, that, the, their, then, there, these, they, this, to, was, will, with.<\/li>\n\n\n\n<li>Synonym token filter \u2013 umo\u017cliwia dodanie synonim\u00f3w dla token\u00f3w i adresuje w ten spos\u00f3b kilka r\u00f3\u017cnych problem\u00f3w, takich jak:<ul><li>skr\u00f3ty: km = kilometr;<\/li><\/ul><ul><li>r\u00f3\u017cnice w zapisie: i-pod = ipod = i pod;<\/li><\/ul><ul><li>synonimy: zm\u0119czony = senny;<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>british vs american: lift = elevator.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Stemmer token filter \u2013 doprowadza s\u0142owa do podstawowej formy, np. lisy, lisica, lisek sprowadzi do s\u0142owa lis.<\/li>\n<\/ul>\n\n\n\n<p>Analyzer mo\u017ce nie posiada\u0107 \u017cadnego token filter, b\u0105d\u017a posiada\u0107 ich wiele. Wtedy zostan\u0105 u\u017cyte w zadeklarowanej kolejno\u015bci.<\/p>\n\n\n\n<p>Wi\u0119cej informacji o token filters mo\u017cna znale\u017a\u0107 <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/analysis-tokenfilters.html\" target=\"_blank\" aria-label=\" (opens in a new tab)\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>.<\/p>\n\n\n\n<p>Po dodatkowe informacje na temat analizy tekstu i samych analyzer\u00f3w odsy\u0142am <a aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/analysis-overview.html\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"ek-link\" rel=\"nofollow\" >tutaj<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Inverted index<\/strong><\/h2>\n\n\n\n<p>Gdy mamy ju\u017c wszystkie tokeny w docelowej postaci, zostaj\u0105 one zapisane jako inverted index. Inverted index przechowuje tokeny oraz miejsce (identyfikator dokumentu), w kt\u00f3rym tokeny wyst\u0105pi\u0142y. Najpro\u015bciej wyt\u0142umaczy\u0107 to na przyk\u0142adzie, wi\u0119c we\u017amy pod uwag\u0119 dwa dokumenty:<\/p>\n\n\n\n<p>doc1<br><em>\u201eAla ma kota\u201d<\/em><\/p>\n\n\n\n<p>doc2<br><em>\u201eA sierotka ma rysia i kota\u201d<\/em><\/p>\n\n\n\n<p>Za\u0142\u00f3\u017cmy \u017ce po analizie tokeny wygl\u0105daj\u0105 nast\u0119puj\u0105co:<\/p>\n\n\n\n<p>doc1<br><em>\u201eala, ma, kot\u201d<\/em><\/p>\n\n\n\n<p>doc2<br><em>\u201esierotka, ma, ry\u015b, kot\u201d<\/em><\/p>\n\n\n\n<p>Odwr\u00f3cony index dla powy\u017cszych dokument\u00f3w m\u00f3g\u0142by wygl\u0105da\u0107 nast\u0119puj\u0105co:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><td class=\"has-text-align-center\" data-align=\"center\">token<\/td><td class=\"has-text-align-center\" data-align=\"center\">dokument<\/td><\/tr><\/thead><tbody><tr><td class=\"has-text-align-center\" data-align=\"center\">ala<\/td><td class=\"has-text-align-center\" data-align=\"center\">doc1<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">ma<\/td><td class=\"has-text-align-center\" data-align=\"center\">doc1, doc2<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">kot<\/td><td class=\"has-text-align-center\" data-align=\"center\">doc1, doc2<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">sierotka<\/td><td class=\"has-text-align-center\" data-align=\"center\">doc2<\/td><\/tr><tr><td class=\"has-text-align-center\" data-align=\"center\">ry\u015b<\/td><td class=\"has-text-align-center\" data-align=\"center\">doc2<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Tab. 1 Odwr\u00f3cony index dla dokument\u00f3w<\/figcaption><\/figure>\n\n\n\n<p>Wida\u0107 teraz, dlaczego jeste\u015bmy w stanie tak szybko znale\u017a\u0107 dokument zawieraj\u0105cy interesuj\u0105ce nas s\u0142owo. Jest to oczywi\u015bcie mocno uproszczony przyk\u0142ad, ale dobrze oddaje ide\u0119.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Podsumowanie<\/strong><\/h2>\n\n\n\n<p><strong>Elasticsearch to<\/strong> <strong>bardzo pot\u0119\u017cne narz\u0119dzie<\/strong>, kt\u00f3re nie ogranicza si\u0119 tylko szybkiego do wyszukiwania danych. Potrafi poddawa\u0107 dane analizie (szczeg\u00f3lnie pami\u0119tajmy o danych tekstowych) i prezentowa\u0107 rezultaty dzi\u0119ki wbudowanym narz\u0119dziom. Jest \u0142atwy w rozbudowie, zar\u00f3wno je\u017celi chodzi o zasoby systemowe, jak i integracje z innymi systemami.<\/p>\n\n\n\n<p>Warto pami\u0119ta\u0107, \u017ce Elasticsearch wymaga wiedzy i umiej\u0119tno\u015bci w zakresie konfiguracji oraz zarz\u0105dzania, zw\u0142aszcza w \u015brodowiskach produkcyjnych. Dlatego wa\u017cne jest, aby pozna\u0107 najlepsze praktyki dotycz\u0105ce bezpiecze\u0144stwa, optymalizacji i skalowania, \u017ceby wykorzysta\u0107 pe\u0142ny potencja\u0142 tej platformy.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;25430&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;3&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 3)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Poznaj Elasticsearch \u2013 narz\u0119dzie do przeszukiwania i analizy danych&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 3)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Elasticsearch to rozproszony silnik do przeszukiwania i analizy danych, oparty na bibliotece Apache Lucene (biblioteka do indeksowania i wyszukiwania, licencja &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/poznaj-elasticsearch-narzedzie-do-przeszukiwania-i-analizy-danych\/\">Continued<\/a><\/p>\n","protected":false},"author":583,"featured_media":25455,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1316],"tags":[1831,1830,1546],"class_list":["post-25430","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-miekko","tag-apache","tag-elasticsearch","tag-przeglad-narzedzi"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/11\/Poznaj-Elasticsearch-\u2013-narzedzie-do-przeszukiwania-i-analizy-danych.jpg","category_names":["Development na mi\u0119kko"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/25430"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/583"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=25430"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/25430\/revisions"}],"predecessor-version":[{"id":25454,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/25430\/revisions\/25454"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/25455"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=25430"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=25430"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=25430"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}