zoukankan      html  css  js  c++  java
  • 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");
       }
    没有停止的脚步,只有倒下去的脚步
  • 相关阅读:
    Java 动态代理 两种实现方法
    aspectj ----- 简介
    url中传递中文参数时的转码与解码
    JDK各个版本比较 JDK5~JDK10
    单例开始究竟能问多深及终极解决方案
    Map、Set、List 集合 差别 联系
    HashMap、LinkedHashMap、ConcurrentHashMap、ArrayList、LinkedList 底层实现
    springMVC :interceptors
    Shiro在Spring session管理
    SpringMVC Shiro与filterChainDefinitions
  • 原文地址:https://www.cnblogs.com/hkMblogs/p/13754780.html
Copyright © 2011-2022 走看看