SpringBoot 整合ElasticSearch,实现站内搜索,高亮关键字

ElasticSearch 是目前最风靡的开源框架之一,常用于站内搜索和日志分析。上一篇文章介绍了 ES 和 MySQL 数据同步,本文就介绍 ES 如何集成到 SpringBoot 中,实现基本的查询。 本文主要用于站内搜索,可实现智能分词,高亮关键字等功能,查询速度也很快。 本文采用 ElasticSearch 6.5.0,客户端是 Rest Client

一、整合 SpringBoot

1.pom.xml

<!-- ElasticSearch -->
   <dependency>
     <groupId>org.elasticsearch</groupId>
     <artifactId>elasticsearch</artifactId>
     <version>6.5.0</version>
   </dependency>
   <!-- Java High Level REST Client -->
   <dependency>
     <groupId>org.elasticsearch.client</groupId>
     <artifactId>elasticsearch-rest-high-level-client</artifactId>
     <version>6.5.0</version>
     <exclusions>
       <exclusion>
         <groupId>org.elasticsearch</groupId>
         <artifactId>elasticsearch</artifactId>
       </exclusion>
     </exclusions>
   </dependency>
 

2.配置类 ESConfig.java

package com.liuyanzhao.sens.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * ElasticSearch 配置类
 * 实例化 client
 *
 * @author 言曌
 * @date 2019/2/2 下午3:55
 */
@Configuration
public class ESConfig {
    @Bean
    public RestHighLevelClient client() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http")));
        return client;
    }
}

主要用于创建 client,然后要用的地方只需要注入,而不是在方法里,每次 new 一个。   3. Controller 层

 
@Autowired
   private RestHighLevelClient client;
   /**
    * 搜索
    *
    * @param model model
    * @param page  当前页码
    * @return 模板路径/themes/{theme}/index
    */
   @GetMapping(value = "/search/page/{page}")
   public String searchPage(Model model,
                            @PathVariable(value = "page") Integer page,
                            @RequestParam("keyword") String keyword) {
       //默认显示20条
       Integer size = 20;
       //所有日志数据,分页
       Page posts = new Page(page, size);
      // Page<Post> posts = postService.searchByKeywords(HtmlUtil.escape(keyword), pageable);
       page = page > 0 ? page : 0;
       //search request
       SearchRequest searchRequest = new SearchRequest("blog");
       //search builder
       SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
       sourceBuilder.query(QueryBuilders.matchQuery("postTitle", keyword));
       sourceBuilder.from((page - 1) * size);
       sourceBuilder.size(size);
       sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
       //sort
       sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
       //highlight
       HighlightBuilder highlightBuilder = new HighlightBuilder();
       HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("postTitle");
       highlightTitle.preTags("<span class="highlight">");
       highlightTitle.postTags("</span>");
       highlightBuilder.field(highlightTitle);
       sourceBuilder.highlighter(highlightBuilder);
       // add builder into request
       searchRequest.indices("blog");
       searchRequest.source(sourceBuilder);
       //response
       SearchResponse searchResponse = null;
       try {
           searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
       } catch (IOException e) {
           e.printStackTrace();
       }
       TimeValue took = searchResponse.getTook();
       //search hits
       SearchHits hits = searchResponse.getHits();
       long totalHits = hits.getTotalHits();
       SearchHit[] searchHits = hits.getHits();
       List<EsPost> postList = new ArrayList<>();
       posts.setTotal((int) totalHits);
       for (SearchHit hit : searchHits) {
           String str = hit.getSourceAsString();
           EsPost esPost = JSONObject.parseObject(str, EsPost.class);
           Map<String, HighlightField> highlightFields = hit.getHighlightFields();
           HighlightField highlight = highlightFields.get("postTitle");
           if (highlight != null) {
               Text[] fragments = highlight.fragments();
               String fragmentString = fragments[0].string();
               esPost.setPostTitle(fragmentString);
           }
           postList.add(esPost);
       }
       posts.setRecords(postList);
       model.addAttribute("is_index", true);
       model.addAttribute("posts", posts);
       model.addAttribute("prefix", "/search");
       model.addAttribute("suffix", "?keyword=" + keyword);
       model.addAttribute("time", took);
       return this.render("search");
   }
没有停止的脚步,只有倒下去的脚步
原文地址:https://www.cnblogs.com/hkMblogs/p/13754780.html