ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

[ElasticSearch系列六] 使用QueryBuilders、NativeSearchQuery实现es数据库对列表的各种操作{多条件,分页,排序,高亮显示(附高亮工具类)等}

2021-12-07 20:31:02  阅读:977  来源: 互联网

标签:高亮 NativeSearchQuery 封装 查询 附高亮 ElasticSearch new vo QueryBuilders


前言

前面我们已经对spring 和 elasticsearch做了整合,这里便在前面的基础上使用es数据完成我们的项目列表及一系列查询分页排序及高亮等功能

 引入

 先看一下使用es数据完成列表及分页高亮等的效果图

 

 ElasticsearchTemplate 

  • ElasticsearchTemplate 封装ES客户端的一些原生api模板,方便实现一些查询
elasticsearchTemplate.queryForPage   #是查询一个分页列表,用的就是一个对象实例
    NativeSearchQuery                #是springdata中的查询条件
    NativeSearchQueryBuilder         #用于建造一个NativeSearchQuery查询对象
    QueryBuilders                    #设置查询条件,是ES中的类
    SortBuilders                     #设置排序条件
    HighlightBuilder                 #设置高亮显示

QueryBuilders 

  • QueryBuilders是ES中的查询条件构造器
QueryBuilders.boolQuery          #子方法must可多条件联查
QueryBuilders.termQuery          #精确查询指定字段
QueryBuilders.matchQuery         #按分词器进行模糊查询
QueryBuilders.rangeQuery         #按指定字段进行区间范围查询
#  大于等于      .from    .gte   
#  小于等于      .to      .lte    

NativeSearchQuery

  • 原生的查询条件类,用来和ES的一些原生查询方法进行搭配,实现一些比较复杂的查询,最终进行构建.build 可作为ElasticsearchTemplate. queryForPage的参数使用
//构建Search对象
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                //条件
                .withQuery(queryBuilder)
                //排序
                .withSort(SortBuilders.fieldSort("id").order(SortOrder.ASC))
                //高亮
                .withHighlightFields(name, ms)
                //分页
                .withPageable(PageRequest.of(pageNum - 1, pageSize))
                //构建
                .build();

        AggregatedPage<Goods> aggregatedPage = elasticsearchTemplate.queryForPage(build, Goods.class,new Hig());

//queryForPage 参数一: NativeSearchQuery 封装的查询数据对象
               参数二: es对应索引实体类
               参数三: 调用高亮工具类

 总体查询数据至列表页面代码,每一步均有解释

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate; 

    @RequestMapping(value = "list")
    public String list(@ModelAttribute(value = "vo") QueryVo vo, @RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "5") Integer pageSize, Model model){
        //高亮显示
        String pre = "<span style='color:red'>";
        String post = "</span>";
        //指定要高亮的字段将其加上头尾标签
        HighlightBuilder.Field name = new HighlightBuilder.Field("name").preTags(pre).postTags(post);
        HighlightBuilder.Field ms = new HighlightBuilder.Field("ms").preTags(pre).postTags(post);
        //查询高亮结果不分片,不加此条会按分词器高亮显示(数据变少)
        ms.numOfFragments(1);

        //多查询条件  must 可不断添加条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if(StringUtils.isNoneBlank(vo.getName())){
                  //精确查询
                queryBuilder.must(QueryBuilders.termQuery("name.keyword",vo.getName()));
        }
        if(StringUtils.isNoneBlank(vo.getMs())){
                  //模糊查询
                queryBuilder.must(QueryBuilders.matchQuery("ms",vo.getMs()));
        }
        //根据指定字段区间查询   from(gte) 大于等于    to(lte)  小于等于
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
        if(vo.getStartpice() != null){
            rangeQuery.from(vo.getStartpice());
        }
        if(vo.getEndpice() != null){
            rangeQuery.to(vo.getEndpice());
        }
        queryBuilder.must(rangeQuery);

        //构建Search对象
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                //条件
                .withQuery(queryBuilder)
                //排序
                .withSort(SortBuilders.fieldSort("id").order(SortOrder.ASC))
                //高亮
                .withHighlightFields(name, ms)
                //分页
                .withPageable(PageRequest.of(pageNum - 1, pageSize))
                //构建
                .build();

        AggregatedPage<Goods> aggregatedPage = elasticsearchTemplate.queryForPage(build, Goods.class,new Hig());
        //封装分页数据至list集合中
        Page<Goods> page = new Page<>(pageNum, pageSize);
        //填充分页总条数
        page.setTotal(aggregatedPage.getTotalElements());
        //封装至pageinfo内,实现列表
        PageInfo<Goods> pg = new PageInfo<>(page);
        //将es查询到当前页的数据 封装至pg中
        pg.setList(aggregatedPage.getContent());
        
        //传入前端,实现列表页面
        model.addAttribute("pg",pg);
        return "list";
    }

认真看的伙伴可以看出上方我引入了高亮工具类,下面对高亮工具类进行详解(亮点) 

es高亮工具类(可直接复制,亲测有效)

public class Hig implements SearchResultMapper {
    /*
    searchResponse 封装高亮查询结果集
    clazz   要封装的es索引对应实体类对象
    pageable
     */
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> clazz, Pageable pageable) {
        //获取es搜索数据集合对象
        SearchHits hits = searchResponse.getHits();
        //获取高亮搜索后数据的总条数
        long totalHits = hits.getTotalHits();
        //搭建存储数据集合对象
        ArrayList<T> list = new ArrayList<>();
        //判断高亮结果有数据
        if(hits.getHits().length > 0){
            //遍历数据集合
            for (SearchHit searchHit : hits) {
                //获取结果集中所有要高亮字段
                final Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                //把json串转为目标对象
                T t = JSON.parseObject(searchHit.getSourceAsString(), clazz);
                //获取目标对象的所有属性
                Field[] fields = clazz.getDeclaredFields();
                //遍历属性
                for (Field field : fields) {
                    //打破私有封装
                    field.setAccessible(true);
                    如果高亮的字段和要封装的对象的名字一致则值要重新封装
                    if(highlightFields.containsKey(field.getName())){
                        try {
                            //将查询到的数据进行高亮替换
                            field.set(t,highlightFields.get(field.getName()).fragments()[0].toString());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
                //存入数据集合中
                list.add(t);
            }
        }
        //返回数据集合,排序对象,集高亮总条数
        return new AggregatedPageImpl<>(list,pageable,totalHits);
    }
}

解释下高亮是什么? 就是你百度时根据你搜索到的关键字高亮显示的特殊字体,例:下图


Thanks!

标签:高亮,NativeSearchQuery,封装,查询,附高亮,ElasticSearch,new,vo,QueryBuilders
来源: https://blog.csdn.net/m0_62866192/article/details/121608020

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有