[ElasticSearch系列六] 使用QueryBuilders、NativeSearchQuery实现es数据库对列表的各种操作{多条件,分页,排序,高亮显示(附高亮工具类)等}
2021/12/8 2:17:40
本文主要是介绍[ElasticSearch系列六] 使用QueryBuilders、NativeSearchQuery实现es数据库对列表的各种操作{多条件,分页,排序,高亮显示(附高亮工具类)等},对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
前面我们已经对spring 和 elasticsearch做了整合,这里便在前面的基础上使用es数据完成我们的项目列表及一系列查询分页排序及高亮等功能
- [ElasticSearch系列四] spring & elasticSearch (linux) 整合【附图解说】_萌小崔的博客-CSDN博客
引入
先看一下使用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!
这篇关于[ElasticSearch系列六] 使用QueryBuilders、NativeSearchQuery实现es数据库对列表的各种操作{多条件,分页,排序,高亮显示(附高亮工具类)等}的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享