ElasticSearch模拟JD

ElasticSearch模拟JD

导入maven依赖

<properties>
    <java.version>1.8</java.version>
    <elasticsearch.version>7.6.1</elasticsearch.version>
</properties>
<dependencies>
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <!--  ElasticSearch依赖  -->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  </dependency>
 <!--  Lombok依赖  -->
  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <optional>true</optional>
  </dependency>
  <!--  Thymeleaf依赖  -->
  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
  </dependency>
  <!--  FastJSON依赖  -->
  <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.62</version>
  </dependency>
  <!--  JSoup依赖(解析网页)  -->
  <dependency>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
      <version>1.10.2</version>
  </dependency>
</dependencies>

将ElasticSerch注入到SpringBoot

@Configuration
public class ElasticSearchClientConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient() {
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1", 9200, "http")
                )
        );
        return client;
    }
}

将我们需要的数据封装为一个对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content {
    private String title;
    private String img;
    private String price;
}

service层

(爬取数据以及实现搜索)

@Service
public class ContentService {
    @Resource
    private RestHighLevelClient client;

    /**
     * @Author: Aaron
     * @Description: 输入搜索条件后将数据解析存储到ES中,并返回插入是否成功
     * @Date: 2020-05-17 15:01
     * @param: keyword
     * @return: java.lang.Boolean
     **/
    public Boolean parseContent(String keyword) throws IOException {
        //1.使用JSoup解析网页获取数据
        List<Content> contentList = new HtmlParseUtils().parseJD(keyword);
        //2.判断索引是否存在
        GetIndexRequest getIndexRequest = new GetIndexRequest("jd_goods");
        boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
        //3.如果索引不存在则创建jd_goods索引
        if (!exists) {
            CreateIndexRequest createIndexRequest = new CreateIndexRequest("jd_goods");
            client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
        }
        //4.如果成功创建BulkRequest对象,并设置超时时间
        BulkRequest bulkRequest = new BulkRequest();
        bulkRequest.timeout("2m");
        for (int i = 0; i < contentList.size(); i++) {
            bulkRequest.add(
                    new IndexRequest("jd_goods")
                            .source(JSON.toJSONString(contentList.get(i)), XContentType.JSON)
            );
        }
        BulkResponse bulk = client.bulk(bulkRequest, RequestOptions.DEFAULT);
        return !bulk.hasFailures();
    }

    /**
     * @Author: Aaron
     * @Description: 获取数据实现搜索功能
     * @Date: 2020-05-17 15:24
     * @param: keyword
     * @param: pageNo
     * @param: pageSize
     * @return: List<Map < String, Object>>
     **/
    public List<Map<String, Object>> searchPage(String keyword, Integer pageNo,
                                                Integer pageSize) throws IOException {
        //1.分页合理化
        if (pageNo < 1) {
            pageNo = 1;
        }
        //2.创建搜索请求
        SearchRequest searchRequest = new SearchRequest("jd_goods");
        //3.构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //4.开启分页
        searchSourceBuilder.from(pageNo);
        searchSourceBuilder.size(pageSize);
        //5.精准匹配
        TermQueryBuilder termQuery = QueryBuilders.termQuery("title", keyword);
        searchSourceBuilder.query(termQuery);
        //6.关键字高亮
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");//要高亮的属性
        highlightBuilder.requireFieldMatch(false);//关闭多个高亮
        highlightBuilder.preTags("<span style='color:red'>");//高亮的前缀
        highlightBuilder.postTags("</span>");//高亮的后缀
        searchSourceBuilder.highlighter(highlightBuilder);
        //7.设置超时间60s
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //8.将我们的搜素条件放到请求当中
        searchRequest.source(searchSourceBuilder);
        //9.客户端执行搜索请求,返回搜索结果
        SearchResponse search = client.search(searchRequest, RequestOptions.DEFAULT);
        //10.将返回结果封装
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (SearchHit hit : search.getHits().getHits()) {
            //解析高亮的字段(将原来的字段换成我们新的高亮字段)
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title = highlightFields.get("title");
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            if (null != title) {
                Text[] fragments = title.fragments();
                String newTitle = "";
                for (Text fragment : fragments) {
                    newTitle += fragment;
                }
                sourceAsMap.put("title", newTitle);
            }
            mapList.add(sourceAsMap);
        }
        return mapList;
    }

controller层

@RestController
public class ContentController {

    @Resource
    private ContentService contentService;

    @GetMapping("/parseJD/{keyword}")
    public Boolean parse(@PathVariable("keyword") String keyword) throws IOException {
        return contentService.parseContent(keyword);
    }

    @GetMapping("/search/{keyword}/{pageNo}/{pageSize}")
    public List<Map<String, Object>> searchPage(@PathVariable("keyword") String keyword,
                                                @PathVariable(value = "pageNo") Integer pageNo,
                                                @PathVariable("pageSize") Integer pageSize) 
      																			throws IOException {
        return contentService.searchPage(keyword, pageNo, pageSize);
    }
}

简单写一个网页 通过以下路径访问

@Controller
public class IndexController {
    @GetMapping("/")
    public String index(){
        return "index";
    }
}

效果如下

(可以清楚的看到搜索的java关键字高亮)
es

源码如下

Aaron-ES-JD