先看代码:
controller:

//根据关键字搜索
@RequestMapping(value = "/searchWC", produces = "application/json; charset=utf-8")
public Resp searchWC(Integer page, Integer limit, String kw){
    return searchService.searchWC(page, limit, kw);
}
//ft http://localhost:11011/search-api/search/searchWC?page=1&limit=5&kw=白色

serviceImpl:

   @Override
    public Resp searchWC(Integer page, Integer limit, String kw) {
        //todo: 搜索ES中的数据,保存到data中。
        //准备需要用到的变量:搜索请求、存放最终响应数据的Map、搜索源构造器、
        //  高亮构造器、搜索结果、存放搜索结果的List。
        SearchRequest request = new SearchRequest("item");
        Map searchResultMap = new HashMap<>();
        SearchSourceBuilder builder = new SearchSourceBuilder();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        SearchResponse searchResponse = null;
        List list = new ArrayList<>();

        //添加搜索条件:关键字模糊查询、分页、高亮
        if(kw != null && !"".equals(kw)){
            //★★注意这里是matchQuery,不是fuzzyQuery,模糊搜索有空再学★★
            builder.query(QueryBuilders.matchQuery("title", kw).maxExpansions(1));
        }
        builder.from((page - 1) * limit);
        builder.size(limit);
        highlightBuilder.preTags("<em style='color: red'>");
        highlightBuilder.postTags("</em>");
        highlightBuilder.field("title");
        builder.highlighter(highlightBuilder);
        
        //设置查询条件,查询
        request.source(builder);
        try {
            searchResponse = highLevelClient.search(request, RequestOptions.DEFAULT);
            long hitsTotalValue = searchResponse.getHits().getTotalHits().value;//总条数
//            System.out.println("hitsTotalValue: " + hitsTotalValue);//ft
            searchResultMap.put("total", hitsTotalValue);
            //页数(ceil后结果类型是double)
            searchResultMap.put("pages", (long) Math.ceil(hitsTotalValue * 1.0 / limit));
            searchResultMap.put("currPage", page);
            
            //用高亮数据替换原数据
            SearchHits hits = searchResponse.getHits();
            for(SearchHit hit: hits){
                //数据,不包含高亮数据
                Map<String, Object> sourceMap = hit.getSourceAsMap();
                //单独取出高亮数据
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlightTitle = highlightFields.get("title");//注意是数组
                
                if(highlightTitle != null){
                    Text[] fragments = highlightTitle.getFragments();
                    if(fragments != null && fragments.length > 0){
                        //替换(fargment[0]是Text类型的)
                        sourceMap.replace("title", fragments[0].toString());
                    }
                }
                list.add(sourceMap);//循环将数据添加入列表
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        searchResultMap.put("data", list);//设置最终结果数据域

        return Resp.ok("搜索成功", searchResultMap);
    }

小结
1、添加ES场景启动器

<!-- 添加ES的场景启动器的依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

2、yaml配置ES

spring:
  application:
    name: buy-search
  elasticsearch:
    rest:
      uris: 
        - 192.168.66.132:9200

3、准备需要用到的变量
在这里插入图片描述
注:还有一个注入的RestHighLevelClient

结构如下:
在这里插入图片描述
具体调用的方法以及设置页码等参看代码。

加断点查看对应searchResponse数据结构:
在这里插入图片描述
HighlightFields的数据结构:
在这里插入图片描述
对照kinaba结果:

在这里插入图片描述
3、根据结构图,完成相关构造器的配置,调用对应方法,完成查询,处理结果,响应。

最终响应结果:
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐