{"id":1623,"date":"2016-10-04T17:58:02","date_gmt":"2016-10-04T15:58:02","guid":{"rendered":"http:\/\/blog.rabahi.net\/?page_id=1623"},"modified":"2016-10-04T17:58:02","modified_gmt":"2016-10-04T15:58:02","slug":"java-spring-elasticsearch","status":"publish","type":"page","link":"https:\/\/blog.rabahi.net\/?page_id=1623","title":{"rendered":"Java Spring &#8211; ElasticSearch"},"content":{"rendered":"<div id=\"toc_container\" class=\"no_bullets\"><p class=\"toc_title\">Contents<\/p><ul class=\"toc_list\"><li><a href=\"#Prerequistes\"><span class=\"toc_number toc_depth_1\">1<\/span> Prerequistes<\/a><\/li><li><a href=\"#Configuration\"><span class=\"toc_number toc_depth_1\">2<\/span> Configuration<\/a><ul><li><a href=\"#ElasticSearchConfigjava\"><span class=\"toc_number toc_depth_2\">2.1<\/span> ElasticSearchConfig.java<\/a><\/li><li><a href=\"#ArticleRepository\"><span class=\"toc_number toc_depth_2\">2.2<\/span> ArticleRepository<\/a><\/li><li><a href=\"#Model\"><span class=\"toc_number toc_depth_2\">2.3<\/span> Model<\/a><\/li><\/ul><\/li><li><a href=\"#Requests\"><span class=\"toc_number toc_depth_1\">3<\/span> Requests<\/a><ul><li><a href=\"#Search_author_by_name\"><span class=\"toc_number toc_depth_2\">3.1<\/span> Search author by name<\/a><\/li><li><a href=\"#Search_article_by_title\"><span class=\"toc_number toc_depth_2\">3.2<\/span> Search article by title<\/a><\/li><li><a href=\"#Seach_article_when_title_match_at_least_90\"><span class=\"toc_number toc_depth_2\">3.3<\/span> Seach article when title match at least 90%<\/a><\/li><\/ul><\/li><\/ul><\/div>\n<h1><span id=\"Prerequistes\">Prerequistes<\/span><\/h1>\n<p>Please read : <a href=\"?page_id=1549\">Java spring &#8211; quickstart<\/a><\/p>\n<h1><span id=\"Configuration\">Configuration<\/span><\/h1>\n<h2><span id=\"ElasticSearchConfigjava\">ElasticSearchConfig.java<\/span><\/h2>\n<pre lang=\"java\">\r\n@Configuration\r\n@EnableElasticsearchRepositories(basePackages = \"net.rabahi.repository\")\r\npublic class ElasticSearchConfig {\r\n\r\n\t@Value(\"${elasticsearch.home:\/usr\/local\/elasticsearch}\")\r\n\tprivate String elasticsearchHome;\r\n\r\n\tprivate static Logger logger = LoggerFactory.getLogger(ElasticSearchConfig.class);\r\n\r\n\t\/**\r\n\t * @return\r\n\t *\/\r\n\t@Bean\r\n\tpublic Client client() {\r\n\t\ttry {\r\n\t\t\tfinal Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty(\"java.io.tmpdir\")), \"elasticsearch_data\");\r\n\r\n\t\t\t\/\/ @formatter:off\r\n\r\n\t\t\tfinal Settings.Builder elasticsearchSettings =\r\n\t\t\t\t\tSettings.settingsBuilder().put(\"http.enabled\", \"false\")\r\n\t\t\t\t\t.put(\"path.data\", tmpDir.toAbsolutePath().toString())\r\n\t\t\t\t\t.put(\"path.home\", elasticsearchHome);\r\n\t\t\t\/\/ @formatter:on\r\n\r\n\t\t\tlogger.debug(tmpDir.toAbsolutePath().toString());\r\n\r\n\t\t\treturn new NodeBuilder().local(true).settings(elasticsearchSettings.build()).node().client();\r\n\t\t} catch (final IOException ioex) {\r\n\t\t\tlogger.error(\"Cannot create temp dir\", ioex);\r\n\t\t\tthrow new RuntimeException();\r\n\t\t}\r\n\t}\r\n\r\n\t\/**\r\n\t * @return\r\n\t *\/\r\n\t@Bean(name=\"elasticsearchTemplate\")\r\n\tpublic ElasticsearchOperations elasticsearchTemplate() {\r\n\t\treturn new ElasticsearchTemplate(client());\r\n\t}\r\n}\r\n<\/pre>\n<h2><span id=\"ArticleRepository\">ArticleRepository<\/span><\/h2>\n<pre lang=\"java\">\r\n@Repository\r\npublic interface ArticleRepository extends ElasticsearchRepository<Article, String> {\r\n\r\n    \/**\r\n     * @param name\r\n     * @param pageable\r\n     * @return\r\n     *\/\r\n    Page<Article> findByAuthorsName(String name, Pageable pageable);\r\n\r\n    \/**\r\n     * @param name\r\n     * @param pageable\r\n     * @return\r\n     *\/\r\n    @Query(\"{\\\"bool\\\": {\\\"must\\\": [{\\\"match\\\": {\\\"authors.name\\\": \\\"?0\\\"}}]}}\")\r\n    Page<Article> findByAuthorsNameUsingCustomQuery(String name, Pageable pageable);\r\n}\r\n<\/pre>\n<h2><span id=\"Model\">Model<\/span><\/h2>\n<p>The first model, is Author :<\/p>\n<pre lang=\"java\">\r\npublic class Author {\r\n\r\n    private String name;\r\n\r\n    public Author() {\r\n    \t\/\/ empty constructor.\r\n    }\r\n\r\n    public Author(String name) {\r\n        this.name = name;\r\n    }\r\n\r\n    public String getName() {\r\n        return name;\r\n    }\r\n\r\n    public void setName(String name) {\r\n        this.name = name;\r\n    }\r\n}\r\n<\/pre>\n<p>The second model, is Article. An Article can have many authors :<\/p>\n<pre lang=\"java\">\r\n@Document(indexName = \"blog\", type = \"article\")\r\npublic class Article {\r\n\r\n    @Id\r\n    private String id;\r\n\r\n    @MultiField(mainField = @Field(type = String), otherFields = { @InnerField(index = not_analyzed, suffix = \"verbatim\", type = String) })\r\n    private String title;\r\n\r\n    @Field(type = Nested)\r\n    private List<Author> authors;\r\n\r\n    @Field(type = String, index = not_analyzed)\r\n    private String[] tags;\r\n\r\n    public Article() {\r\n    \t\/\/ empty constructor.\r\n    }\r\n\r\n    public Article(String title) {\r\n        this.title = title;\r\n    }\r\n\r\n    public String getId() {\r\n        return id;\r\n    }\r\n\r\n    public void setId(String id) {\r\n        this.id = id;\r\n    }\r\n\r\n    public String getTitle() {\r\n        return title;\r\n    }\r\n\r\n    public void setTitle(String title) {\r\n        this.title = title;\r\n    }\r\n\r\n    public List<Author> getAuthors() {\r\n        return authors;\r\n    }\r\n\r\n    public void setAuthors(List<Author> authors) {\r\n        this.authors = authors;\r\n    }\r\n\r\n    public String[] getTags() {\r\n        return tags;\r\n    }\r\n\r\n    public void setTags(String... tags) {\r\n        this.tags = tags;\r\n    }    \r\n}\r\n<\/pre>\n<h1><span id=\"Requests\">Requests<\/span><\/h1>\n<h2><span id=\"Search_author_by_name\">Search author by name<\/span><\/h2>\n<pre lang=\"java\">\r\n\/\/ request :\r\nfinal Page<Article> articleByAuthorName = articleService.findByAuthorName(authorName, new PageRequest(0, 10));\r\n\r\n\/\/ the number of results :\r\narticleByAuthorName.getContent().size();\r\n\r\n\/\/ the result list :\r\narticleByAuthorName.getContent();\r\n<\/pre>\n<h2><span id=\"Search_article_by_title\">Search article by title<\/span><\/h2>\n<pre lang=\"java\">\r\n\/\/ request :\r\nfinal SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery(\"title\", articleTitle))\r\n\t\t\t\t.build();\r\nList<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);\r\n\r\n\/\/ the number of results :\r\narticles.size();\r\n\r\n\/\/ the result list :\r\narticles;\r\n<\/pre>\n<h2><span id=\"Seach_article_when_title_match_at_least_90\">Seach article when title match at least 90%<\/span><\/h2>\n<pre lang=\"java\">\r\n\/\/ request :\r\nfinal SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(QueryBuilders.matchQuery(\"title\", articleTitle)\r\n\t\t\t\t.minimumShouldMatch(\"90%\"))\r\n\t\t\t\t.build();\r\n\t\tList<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);\r\n\r\n\/\/ the number of results :\r\narticles.size();\r\n\r\n\/\/ the result list :\r\narticles;\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Contents1 Prerequistes2 Configuration2.1 ElasticSearchConfig.java2.2 ArticleRepository2.3 Model3 Requests3.1 Search author by name3.2 Search article by title3.3 Seach article when title match at least 90% Prerequistes Please read : Java spring &#8211; quickstart Configuration ElasticSearchConfig.java @Configuration @EnableElasticsearchRepositories(basePackages = &#8220;net.rabahi.repository&#8221;) public class ElasticSearchConfig { @Value(&#8220;${elasticsearch.home:\/usr\/local\/elasticsearch}&#8221;) private String elasticsearchHome; private static Logger logger = LoggerFactory.getLogger(ElasticSearchConfig.class); \/** * @return *\/ [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1547,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1623","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/pages\/1623","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1623"}],"version-history":[{"count":1,"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/pages\/1623\/revisions"}],"predecessor-version":[{"id":1624,"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/pages\/1623\/revisions\/1624"}],"up":[{"embeddable":true,"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=\/wp\/v2\/pages\/1547"}],"wp:attachment":[{"href":"https:\/\/blog.rabahi.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1623"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}