{"id":344,"date":"2020-05-12T10:03:56","date_gmt":"2020-05-12T08:03:56","guid":{"rendered":"https:\/\/arasoftware.pl\/?p=344"},"modified":"2021-10-21T10:34:26","modified_gmt":"2021-10-21T08:34:26","slug":"spring-boot-elasticsearch","status":"publish","type":"post","link":"https:\/\/arasoftware.pl\/en\/spring-boot-elasticsearch\/","title":{"rendered":"Spring Boot i Elasticsearch"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Czas czytania: <\/span> <span class=\"rt-time\">5<\/span> <span class=\"rt-label rt-postfix\">minut<\/span><\/span><p class=\"wp-block-paragraph\">Elasticsearch to dokumentowa baza danych, kt&oacute;ra udost&#281;pnia bardzo sprawny mechanizm wyszukiwania pe&#322;notekstowego. Jest to pot&#281;&#380;ne narz&#281;dzie oparte na Apache Lucece, kt&oacute;re umo&#380;liwia przeszukiwanie danych w czasie niemal&#380;e rzeczywistym. Dodatkowo udost&#281;pnia przyjazne API, dzi&#281;ki kt&oacute;remu mo&#380;na w &#322;atwy i przyjazny u&#380;ytkownikowi spos&oacute;b, zarz&#261;dza&#263; t&#261; baz&#261; danych.<\/p>\n\n\n<p class=\"wp-block-paragraph\">Wielu z nas, programist&oacute;w, do&#347;wiadczy&#322;o kiedy&#347; problemu z wydajno&#347;ci&#261; du&#380;ej bazy danych podczas wyszukiwania w niej informacji. Zw&#322;aszcza je&#347;li du&#380;a cz&#281;&#347;&#263; danych w tej bazie by&#322;a tekstowa. Sam widzia&#322;em niejednokrotnie jak wolno mo&#380;e dzia&#322;a&#263; aplikacja je&#347;li nikt wcze&#347;niej nie zadba&#322; o poprawn&#261; struktur&#281; bazy danych. Brak normalizacji bazy, duplikaty danych oraz nieoptymalne wyszukiwanie sprawia&#322;y &#380;e po jakim&#347; czasie, gdy ju&#380; baza nape&#322;ni&#322;a si&#281; danymi to aplikacja dzia&#322;a&#322;a co raz wolniej.<\/p>\n\n\n<p class=\"wp-block-paragraph\">Jak unikn&#261;&#263; chocia&#380; cz&#281;&#347;ci z tych problem&oacute;w? Jak sprawi&#263; &#380;eby Twoja aplikacja dzia&#322;a&#322;a p&#322;ynnie po mimo ogromu danych jakie generuje? Z pomoc&#261; przychodzi Elasticsearch.<\/p>\n\n\n<h2 class=\"wp-block-heading wp-block-heading\" id=\"uruchomienie-elasticsearch-na-dockerze\">Uruchomienie Elasticsearch na dockerze<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Przejd&#378;my wi&#281;c do przyk&#322;adu, w kt&oacute;rym po&#322;&#261;czymy aplikacj&#281; opart&#261; o Spring Boot z Elasticsearch. Na pocz&#261;tek uruchommy sobie dockera z us&#322;ug&#261; Elasticsearch. Je&#347;li nie wiesz jak to zrobi&#263;, to zach&#281;cam do zapoznania si&#281; z dokumentacj&#261; techniczn&#261; dost&#281;pn&#261; pod adresem <a rel=\"noreferrer noopener\" aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/docker.html\" target=\"_blank\"> <\/a> <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/docker.html\">https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/docker.html<\/a><\/p>\n\n\n<p class=\"wp-block-paragraph\">Uruchomienie obrazu Elasticsearch sprowadza si&#281; do wywo&#322;ania komendy:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">docker run -p 9200:9200 -p 9300:9300 -e \"discovery.type=single-node\" docker.elastic.co\/elasticsearch\/elasticsearch:7.6.2<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Po poprawnym odpaleniu dockera oraz wej&#347;ciu na &#8222;http:\/\/localhost:9200&#8221;, w oknie przegl&#261;darki powinni&#347;my otrzyma&#263; poni&#380;szy response:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json line-numbers\">{\n  \"name\" : \"2b22d9ccf50b\",\n  \"cluster_name\" : \"docker-cluster\",\n  \"cluster_uuid\" : \"TT6pCY7mTWmm8KWiRNMyPQ\",\n  \"version\" : {\n    \"number\" : \"7.6.2\",\n    \"build_flavor\" : \"default\",\n    \"build_type\" : \"docker\",\n    \"build_hash\" : \"ef48eb35cf30adf4db14086e8aabd07ef6fb113f\",\n    \"build_date\" : \"2020-03-26T06:34:37.794943Z\",\n    \"build_snapshot\" : false,\n    \"lucene_version\" : \"8.4.0\",\n    \"minimum_wire_compatibility_version\" : \"6.8.0\",\n    \"minimum_index_compatibility_version\" : \"6.0.0-beta1\"\n  },\n  \"tagline\" : \"You Know, for Search\"\n}<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Warto w tym miejscu doda&#263;, &#380;e Elasticsearch udost&#281;pnia REST API na porcie 9200. Dzi&#281;ki temu rozwi&#261;zaniu mo&#380;emy u&#380;ywa&#263; tej bazy tak&#380;e za pomoc&#261; u&#380;ytecznego API, opisanego tutaj:  <a href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/rest-apis.html\">https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/rest-apis.html<\/a>.<\/p>\n\n\n<h2 class=\"wp-block-heading wp-block-heading\" id=\"przykc582ad-integracji-spring-boot-i-elasticsearch\">Przyk&#322;ad integracji Spring Boot i Elasticsearch<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Je&#347;li docker z Elasticsearch dzia&#322;a poprawnie, to mo&#380;emy przej&#347;&#263; do implementacji aplikacji w Spring Boot. B&#281;dzie si&#281; ona &#322;&#261;czy&#263; bezpo&#347;rednio z Elasticsearch za pomoc&#261; Spring Data Elasticsearch. Jest to dedykowana zale&#380;no&#347;&#263; do Springa, kt&oacute;ra w &#322;atwy i prosty spos&oacute;b pozwala wywo&#322;ywa&#263; requesty do Elasticsearch, za pomoc&#261; interfejs&oacute;w analogicznych do tych z Spring Data.<\/p>\n\n\n<p class=\"wp-block-paragraph\">Poni&#380;ej znajduje si&#281; plik &#8222;pom.xml&#8221;, w kt&oacute;rym znajduje si&#281; dodany starter <code class=\"\">spring-boot-starter-data-elasticsearch<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"pom.xml\"><code lang=\"xml\" class=\"language-xml line-numbers\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?>\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n         xsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 https:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\">\n    &lt;modelVersion>4.0.0&lt;\/modelVersion>\n    &lt;parent>\n        &lt;groupId>org.springframework.boot&lt;\/groupId>\n        &lt;artifactId>spring-boot-starter-parent&lt;\/artifactId>\n        &lt;version>2.2.6.RELEASE&lt;\/version>\n        &lt;relativePath\/> &lt;!-- lookup parent from repository -->\n    &lt;\/parent>\n    &lt;groupId>com.ara&lt;\/groupId>\n    &lt;artifactId>elastic&lt;\/artifactId>\n    &lt;version>0.0.1-SNAPSHOT&lt;\/version>\n    &lt;name>elastic&lt;\/name>\n    &lt;description>Demo project for Spring Boot and Elasticsearch integration&lt;\/description>\n\n    &lt;properties>\n        &lt;java.version>1.8&lt;\/java.version>\n    &lt;\/properties>\n\n    &lt;dependencies>\n        &lt;dependency>\n            &lt;groupId>org.springframework.boot&lt;\/groupId>\n            &lt;artifactId>spring-boot-starter-data-elasticsearch&lt;\/artifactId>\n        &lt;\/dependency>\n        &lt;dependency>\n            &lt;groupId>org.springframework.boot&lt;\/groupId>\n            &lt;artifactId>spring-boot-starter-web&lt;\/artifactId>\n        &lt;\/dependency>\n\n        &lt;dependency>\n            &lt;groupId>org.projectlombok&lt;\/groupId>\n            &lt;artifactId>lombok&lt;\/artifactId>\n            &lt;optional>true&lt;\/optional>\n        &lt;\/dependency>\n        &lt;dependency>\n            &lt;groupId>org.springframework.boot&lt;\/groupId>\n            &lt;artifactId>spring-boot-starter-test&lt;\/artifactId>\n            &lt;scope>test&lt;\/scope>\n            &lt;exclusions>\n                &lt;exclusion>\n                    &lt;groupId>org.junit.vintage&lt;\/groupId>\n                    &lt;artifactId>junit-vintage-engine&lt;\/artifactId>\n                &lt;\/exclusion>\n            &lt;\/exclusions>\n        &lt;\/dependency>\n    &lt;\/dependencies>\n\n    &lt;build>\n        &lt;plugins>\n            &lt;plugin>\n                &lt;groupId>org.springframework.boot&lt;\/groupId>\n                &lt;artifactId>spring-boot-maven-plugin&lt;\/artifactId>\n            &lt;\/plugin>\n        &lt;\/plugins>\n    &lt;\/build>\n\n&lt;\/project>\n\n<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Warto zauwa&#380;y&#263;, &#380;e doda&#322;em do projektu zale&#380;no&#347;ci projektu Lombok. Pomo&#380;e to w p&oacute;&#378;niejszej implementacji aplikacji. <\/p>\n\n\n<p class=\"wp-block-paragraph\">Kolejnym krokiem jest zdefiniowanie po&#322;&#261;czenia po mi&#281;dzy nasz&#261; aplikacj&#261;, a us&#322;ug&#261; Elasticsearch, kt&oacute;r&#261; przed chwil&#261; uruchomili&#347;my na dockerze. W tym celu dodamy poni&#380;sz&#261; klas&#281; &#8222;EsConfig.java&#8221;. Jest to klasa konfiguracyjna, kt&oacute;ra dostarcza nam deificej&#281; dw&oacute;ch bean&oacute;w; Client i ElasticsearchOperations. Odpowiadaj&#261; one odpowiednio za mo&#380;liwo&#347;&#263; po&#322;&#261;czenia si&#281; z us&#322;ug&#261; Elasticsearch oraz za zdefiniowanie operacji, kt&oacute;re mog&#261; by&#263; wykonywane na tej us&#322;udze.<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"EsConfig.java\"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic;\n\nimport org.elasticsearch.client.Client;\nimport org.elasticsearch.client.transport.TransportClient;\nimport org.elasticsearch.common.settings.Settings;\nimport org.elasticsearch.common.transport.TransportAddress;\nimport org.elasticsearch.transport.client.PreBuiltTransportClient;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.data.elasticsearch.core.ElasticsearchOperations;\nimport org.springframework.data.elasticsearch.core.ElasticsearchTemplate;\nimport org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;\n\nimport java.net.InetAddress;\nimport java.net.UnknownHostException;\n\n@Configuration\n@EnableElasticsearchRepositories\npublic class EsConfig {\n\n    @Value(\"${elasticsearch.cluster.name:docker-cluster}\")\n    private String clusterName;\n\n    @Value(\"${elasticsearch.host}\")\n    private String elasticsearchHost;\n\n    @Value(\"#{new Integer('${elasticsearch.port}')}\")\n    private Integer elasticsearchPort;\n\n    @Bean\n    public Client client() throws UnknownHostException {\n        TransportClient client = new PreBuiltTransportClient(Settings.builder()\n                .put(\"cluster.name\", clusterName)\n                .build());\n        client.addTransportAddress(new TransportAddress(InetAddress.getByName(elasticsearchHost), elasticsearchPort));\n        return client;\n    }\n\n    @Bean\n    public ElasticsearchOperations elasticsearchTemplate() throws UnknownHostException {\n        return new ElasticsearchTemplate(client());\n    }\n}<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Do pliku konfiguracyjnego &#8222;application.properties&#8221;, w celu zdefiniowania danych dost&#281;powych do us&#322;ugi Elasticsearch, nale&#380;y doda&#263; poni&#380;sze parametry:<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"application.properties\"><code lang=\"properties\" class=\"language-properties line-numbers\">elasticsearch.host=127.0.0.1\nelasticsearch.port=9300\nelasticsearch.cluster.name=docker-cluster<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Klasa &#8222;Post.java&#8221; b&#281;dzie nasz&#261; encj&#261; poddawan&#261; persystencji w bazie danych.<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"Post.java\"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic.model;\n\nimport lombok.AllArgsConstructor;\nimport lombok.Getter;\nimport lombok.NoArgsConstructor;\nimport lombok.Setter;\nimport org.springframework.data.annotation.Id;\nimport org.springframework.data.elasticsearch.annotations.Document;\n\n@Getter\n@Setter\n@NoArgsConstructor\n@AllArgsConstructor\n@Document(indexName = \"blog\", type = \"post\")\npublic class Post {\n\n    @Id\n    private String id;\n    private String title;\n    private String content;\n    private boolean isPublished;\n    private String author;\n}\n<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Warto zauwa&#380;y&#263; &#380;e nie ma tutaj klasycznych getter&oacute;w, setter&oacute;w i konstrukrot&oacute;w, a wszystko dzieje si&#281; dzi&#281;ki Lombok&#8217;owi i jego adnotacjom:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@Getter\n@Setter\n@NoArgsConstructor\n@AllArgsConstructor<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Lecz najwa&#380;niejsza dla nas jest adnotacja:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@Document(indexName = \"blog\", type = \"post\")<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Pozwola ona na zapis obiektu &#8222;Post&#8221; do bazy danych Elasticsearch. Adnotacja &#8222;@Document&#8221; przyjmuje w tym wypadku dwa parametry:<\/p>\n\n\n<ul class=\"wp-block-list wp-block-list\" style=\"\">\n<li>indexName &#8211; nazwa unikalnego indeksu. <\/li>\n<li>type &#8211; nazwa encji (unikalna w ramach indeksu)<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p>Je\u015bli chcesz wiedzie\u0107 wi\u0119cej na temat indeksowania danych w Elasticseach, to polecam ten post  <a rel=\"noreferrer noopener\" aria-label=\" (otwiera si\u0119 na nowej zak\u0142adce)\" href=\"https:\/\/czterytygodnie.pl\/sposoby-wyszukiwania-elasticsearch\/\" target=\"_blank\">https:\/\/czterytygodnie.pl\/sposoby-wyszukiwania-elasticsearch\/<\/a> <\/p><\/blockquote>\n\n\n<p class=\"wp-block-paragraph\">Kolejnym krokiem jest zaimplementowanie interfejsu rozszerzaj&#261;cego &#8222;ElasticsearchRepository&#8221;. B&#281;dzie on dostarcza&#322; nam predefiniowane metody, dzi&#281;ki kt&oacute;rym b&#281;dziemy mogli w &#322;atwy spos&oacute;b zarz&#261;dza&#263; obiektem Post w bazie danych. Jak ju&#380; wspomnia&#322;em wcze&#347;niej, jest to nic innego jak odpowiednik interfejsu &#8222;Repository&#8221; ze Spring Data.<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"PostRepository.java\"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic.repository;\n\nimport com.ara.elastic.model.Post;\nimport org.springframework.data.elasticsearch.repository.ElasticsearchRepository;\n\npublic interface PostRepository extends ElasticsearchRepository&lt;Post, String> {\n}<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Stw&oacute;rzmy teraz serwis w formie interfejsu, kt&oacute;ry b&#281;dzie dostarcza&#322; definicji metod do zarz&#261;dzania obiektem Post.<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"PostService \"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic.service;\n\nimport com.ara.elastic.model.Post;\n\nimport java.util.List;\n\npublic interface PostService {\n\n    String save(Post post);\n    void delete(String postId);\n\n    Post findById(String postId);\n    List&lt;Post> findAll();\n    List&lt;Post> findAllByPhrase(String phrase);\n}<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Implementacja tego serwisu mo&#380;e wygl&#261;da&#263; nast&#281;puj&#261;co:<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"PostServiceImpl \"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic.service.impl;\n\nimport com.ara.elastic.model.Post;\nimport com.ara.elastic.repository.PostRepository;\nimport com.ara.elastic.service.PostService;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.data.domain.PageImpl;\nimport org.springframework.data.elasticsearch.core.ElasticsearchTemplate;\nimport org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;\nimport org.springframework.data.elasticsearch.core.query.SearchQuery;\nimport org.springframework.stereotype.Service;\n\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.UUID;\n\nimport static org.elasticsearch.index.query.QueryBuilders.regexpQuery;\n\n@Service\npublic class PostServiceImpl implements PostService {\n\n    @Autowired\n    private PostRepository postRepository;\n\n    @Autowired\n    private ElasticsearchTemplate esTemplate;\n\n    @Override\n    public String save(Post post) {\n        assignId(post);\n        postRepository.save(post);\n        return post.getId();\n    }\n\n    @Override\n    public void delete(String postId) {\n        Optional&lt;Post> post = postRepository.findById(postId);\n        post.ifPresent(post1 -> postRepository.delete(post1));\n    }\n\n    @Override\n    public Post findById(String postId) {\n        Optional&lt;Post> post = postRepository.findById(postId);\n        return post.orElse(null);\n    }\n\n    @Override\n    public List&lt;Post> findAll() {\n        return ((PageImpl)postRepository.findAll()).getContent();\n    }\n\n    @Override\n    public List&lt;Post> findAllByPhrase(String phrase) {\n        SearchQuery searchQuery = new NativeSearchQueryBuilder()\n                .withFilter(regexpQuery(\"content\", \".*\" + phrase + \".*\"))\n                .build();\n        return esTemplate.queryForList(searchQuery, Post.class);\n    }\n\n    private void assignId(Post post) {\n        if (post.getId() == null)\n            post.setId(UUID.randomUUID().toString());\n    }\n}\n<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Mamy ju&#380; logi&#281; biznesow&#261; nasze aplikacji, wi&#281;c dodajmy jeszcze API aby mo&#380;na by&#322;o jej u&#380;ywa&#263; \ud83d\ude42<\/p>\n\n\n<p class=\"wp-block-paragraph\">W poni&#380;szym kontrolerze s&#261; zdefiniowane metody do zapisu, usuwania i wyszukiwania obiekt&oacute;w typu Post.<\/p>\n\n\n\n<pre class=\"wp-block-code\" title=\"PostController.java\"><code lang=\"java\" class=\"language-java line-numbers\">package com.ara.elastic.controller;\n\nimport com.ara.elastic.model.Post;\nimport com.ara.elastic.service.PostService;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.web.bind.annotation.*;\n\nimport java.util.List;\n\n@RestController\npublic class PostController {\n\n    @Autowired\n    private PostService postService;\n\n    @RequestMapping(value = \"save\", method = RequestMethod.POST)\n    public String save(@RequestBody Post post) {\n        return postService.save(post);\n    }\n\n    @RequestMapping(value = \"all\", method = RequestMethod.GET)\n    public List&lt;Post> findAll(){\n        return postService.findAll();\n    }\n\n    @RequestMapping(value = \"phrase\", method = RequestMethod.GET)\n    public List&lt;Post> findByPhrase(@RequestParam(\"phrase\") String phrase){\n        return postService.findAllByPhrase(phrase);\n    }\n\n    @RequestMapping(value = \"\", method = RequestMethod.GET)\n    public Post findById(@RequestParam(\"id\") String id){\n        return postService.findById(id);\n    }\n\n    @RequestMapping(value = \"\", method = RequestMethod.DELETE)\n    public void deleteById(@RequestParam(\"id\") String id){\n        postService.delete(id);\n    }\n}<\/code><\/pre>\n\n\n<h2 class=\"wp-block-heading wp-block-heading\" id=\"podsumowanie\">Podsumowanie<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Reasumuj&#261;c, Elasticsearch doskonale sprawdzi si&#281; jako baza danych w aplikacjach, kt&oacute;re przetwarzaj&#261; du&#380;e ilo&#347;ci danych tekstowych i potrzebuj&#261; robi&#263; to w jak najkr&oacute;tszym czasie. Przesukiwanie pe&#322;notekstowe jest tutaj u&#322;atwione i przyspieszone dzi&#281;ki indeksacji zasob&oacute;w w Elasticsearch.<\/p>\n\n\n\n\n\n<p class=\"wp-block-paragraph\"><br>Poni&#380;ej znajduj&#261; si&#281; przydatne linki, w&#347;r&oacute;d kt&oacute;rych znajdziesz te&#380; link do mojego Github&#8217;a i do projektu, u&#380;ytego w tym po&#347;cie.<\/p>\n\n\n<p class=\"wp-block-paragraph\"> <a aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" rel=\"noreferrer noopener\" href=\"https:\/\/www.elastic.co\/\" target=\"_blank\">https:\/\/www.elastic.co\/<\/a> <br><a aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" rel=\"noreferrer noopener\" href=\"https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/docker.html\" target=\"_blank\">https:\/\/www.elastic.co\/guide\/en\/elasticsearch\/reference\/current\/docker.html<\/a><br> <a aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" rel=\"noreferrer noopener\" href=\"https:\/\/www.docker.com\/\" target=\"_blank\">https:\/\/www.docker.com\/<\/a> <br> <a aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" rel=\"noreferrer noopener\" href=\"https:\/\/projectlombok.org\/\" target=\"_blank\">https:\/\/projectlombok.org\/<\/a><br> <a aria-label=\" (otwiera si&#281; na nowej zak&#322;adce)\" rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/radek-osak\/spring-boot-elasticsearch\" target=\"_blank\">https:\/\/github.com\/radek-osak\/spring-boot-elasticsearch<\/a> <br><a href=\"https:\/\/arasoftware.pl\/2020\/07\/01\/programowanie-reaktywne\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/arasoftware.pl\/2020\/07\/01\/programowanie-reaktywne\/<\/a><\/p>\n\n\n<p class=\"wp-block-paragraph\">Zach&#281;cam do zapoznania si&#281; z innymi postami na moim blogu, pozostawienie komentarza oraz udost&#281;pnienie tego wpisu je&#347;li Ci si&#281; spodoba&#322;!<\/p>","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Czas czytania: <\/span> <span class=\"rt-time\">5<\/span> <span class=\"rt-label rt-postfix\">minut<\/span><\/span> Elasticsearch to dokumentowa baza danych, kt&oacute;ra udost&#281;pnia bardzo sprawny mechanizm wyszukiwania pe&#322;notekstowego. Jest to pot&#281;&#380;ne narz&#281;dzie oparte na Apache Lucece, kt&oacute;re umo&#380;liwia przeszukiwanie danych w czasie niemal&#380;e rzeczywistym. Dodatkowo udost&#281;pnia przyjazne API, dzi&#281;ki kt&oacute;remu mo&#380;na w &#322;atwy i przyjazny u&#380;ytkownikowi spos&oacute;b, zarz&#261;dza&#263; t&#261; baz&#261; danych. Wielu z nas, programist&oacute;w, do&#347;wiadczy&#322;o kiedy&#347; problemu z wydajno&#347;ci&#261; du&#380;ej &hellip;<\/p>","protected":false},"author":1,"featured_media":955,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13,19],"tags":[17,15,18,14],"class_list":["post-344","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programowanie","category-spring-boot","tag-docker","tag-elasticsearch","tag-java","tag-spring-boot"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.11 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Spring Boot i Elasticsearch - Ara Software<\/title>\n<meta name=\"description\" content=\"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/arasoftware.pl\/en\/spring-boot-elasticsearch\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring Boot i Elasticsearch - Ara Software\" \/>\n<meta property=\"og:description\" content=\"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego\" \/>\n<meta property=\"og:url\" content=\"https:\/\/arasoftware.pl\/en\/spring-boot-elasticsearch\/\" \/>\n<meta property=\"og:site_name\" content=\"Ara Software\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-12T08:03:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-10-21T08:34:26+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/arasoftware.pl\/wp-content\/uploads\/2020\/07\/elastic-springboot.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1080\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Radek Osak\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Radek Osak\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/\"},\"author\":{\"name\":\"Radek Osak\",\"@id\":\"https:\/\/arasoftware.pl\/#\/schema\/person\/a13fe68bd27e762ef255547a88956902\"},\"headline\":\"Spring Boot i Elasticsearch\",\"datePublished\":\"2020-05-12T08:03:56+00:00\",\"dateModified\":\"2021-10-21T08:34:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/\"},\"wordCount\":858,\"publisher\":{\"@id\":\"https:\/\/arasoftware.pl\/#organization\"},\"keywords\":[\"Docker\",\"ElasticSearch\",\"Java\",\"Spring Boot\"],\"articleSection\":[\"Programowanie\",\"Spring Boot\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/\",\"url\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/\",\"name\":\"Spring Boot i Elasticsearch - Ara Software\",\"isPartOf\":{\"@id\":\"https:\/\/arasoftware.pl\/#website\"},\"datePublished\":\"2020-05-12T08:03:56+00:00\",\"dateModified\":\"2021-10-21T08:34:26+00:00\",\"description\":\"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego\",\"breadcrumb\":{\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Strona g\u0142\u00f3wna\",\"item\":\"https:\/\/arasoftware.pl\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Spring Boot i Elasticsearch\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/arasoftware.pl\/#website\",\"url\":\"https:\/\/arasoftware.pl\/\",\"name\":\"Ara Software\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/arasoftware.pl\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/arasoftware.pl\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/arasoftware.pl\/#organization\",\"name\":\"Ara Software\",\"url\":\"https:\/\/arasoftware.pl\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/arasoftware.pl\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/arasoftware.pl\/wp-content\/uploads\/2023\/06\/ara-logo-light-1.svg\",\"contentUrl\":\"https:\/\/arasoftware.pl\/wp-content\/uploads\/2023\/06\/ara-logo-light-1.svg\",\"width\":317,\"height\":55,\"caption\":\"Ara Software\"},\"image\":{\"@id\":\"https:\/\/arasoftware.pl\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/arasoftware.pl\/#\/schema\/person\/a13fe68bd27e762ef255547a88956902\",\"name\":\"Radek Osak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/arasoftware.pl\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2a5a97fd24033c3df7dff799dc95774b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2a5a97fd24033c3df7dff799dc95774b?s=96&d=mm&r=g\",\"caption\":\"Radek Osak\"},\"url\":\"https:\/\/arasoftware.pl\/en\/author\/radek030790gmail-com\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring Boot i Elasticsearch - Ara Software","description":"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/arasoftware.pl\/en\/spring-boot-elasticsearch\/","og_locale":"en_US","og_type":"article","og_title":"Spring Boot i Elasticsearch - Ara Software","og_description":"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego","og_url":"https:\/\/arasoftware.pl\/en\/spring-boot-elasticsearch\/","og_site_name":"Ara Software","article_published_time":"2020-05-12T08:03:56+00:00","article_modified_time":"2021-10-21T08:34:26+00:00","og_image":[{"width":1920,"height":1080,"url":"https:\/\/arasoftware.pl\/wp-content\/uploads\/2020\/07\/elastic-springboot.png","type":"image\/png"}],"author":"Radek Osak","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Radek Osak","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#article","isPartOf":{"@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/"},"author":{"name":"Radek Osak","@id":"https:\/\/arasoftware.pl\/#\/schema\/person\/a13fe68bd27e762ef255547a88956902"},"headline":"Spring Boot i Elasticsearch","datePublished":"2020-05-12T08:03:56+00:00","dateModified":"2021-10-21T08:34:26+00:00","mainEntityOfPage":{"@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/"},"wordCount":858,"publisher":{"@id":"https:\/\/arasoftware.pl\/#organization"},"keywords":["Docker","ElasticSearch","Java","Spring Boot"],"articleSection":["Programowanie","Spring Boot"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/","url":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/","name":"Spring Boot i Elasticsearch - Ara Software","isPartOf":{"@id":"https:\/\/arasoftware.pl\/#website"},"datePublished":"2020-05-12T08:03:56+00:00","dateModified":"2021-10-21T08:34:26+00:00","description":"Elasticsearch to dokumentowa baza danych, kt\u00f3ra udost\u0119pnia bardzo sprawny mechanizm wyszukiwania pe\u0142notekstowego","breadcrumb":{"@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/arasoftware.pl\/spring-boot-elasticsearch\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Strona g\u0142\u00f3wna","item":"https:\/\/arasoftware.pl\/"},{"@type":"ListItem","position":2,"name":"Spring Boot i Elasticsearch"}]},{"@type":"WebSite","@id":"https:\/\/arasoftware.pl\/#website","url":"https:\/\/arasoftware.pl\/","name":"Ara Software","description":"","publisher":{"@id":"https:\/\/arasoftware.pl\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/arasoftware.pl\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/arasoftware.pl\/#organization","name":"Ara Software","url":"https:\/\/arasoftware.pl\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/arasoftware.pl\/#\/schema\/logo\/image\/","url":"https:\/\/arasoftware.pl\/wp-content\/uploads\/2023\/06\/ara-logo-light-1.svg","contentUrl":"https:\/\/arasoftware.pl\/wp-content\/uploads\/2023\/06\/ara-logo-light-1.svg","width":317,"height":55,"caption":"Ara Software"},"image":{"@id":"https:\/\/arasoftware.pl\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/arasoftware.pl\/#\/schema\/person\/a13fe68bd27e762ef255547a88956902","name":"Radek Osak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/arasoftware.pl\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2a5a97fd24033c3df7dff799dc95774b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2a5a97fd24033c3df7dff799dc95774b?s=96&d=mm&r=g","caption":"Radek Osak"},"url":"https:\/\/arasoftware.pl\/en\/author\/radek030790gmail-com\/"}]}},"_links":{"self":[{"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/posts\/344","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/comments?post=344"}],"version-history":[{"count":0,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/posts\/344\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/media\/955"}],"wp:attachment":[{"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/media?parent=344"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/categories?post=344"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/arasoftware.pl\/en\/wp-json\/wp\/v2\/tags?post=344"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}