前面我们已经对spring 和 elasticsearch做了整合,这里便在前面的基础上使用es数据完成我们的项目列表及一系列查询分页排序及高亮等功能
- [ElasticSearch系列四] spring & elasticSearch (linux) 整合【附图解说】_萌小崔的博客-CSDN博客
先看一下使用es数据完成列表及分页高亮等的效果图
elasticsearchTemplate.queryForPage #是查询一个分页列表,用的就是一个对象实例 NativeSearchQuery #是springdata中的查询条件 NativeSearchQueryBuilder #用于建造一个NativeSearchQuery查询对象 QueryBuilders #设置查询条件,是ES中的类 SortBuilders #设置排序条件 HighlightBuilder #设置高亮显示
QueryBuilders.boolQuery #子方法must可多条件联查 QueryBuilders.termQuery #精确查询指定字段 QueryBuilders.matchQuery #按分词器进行模糊查询 QueryBuilders.rangeQuery #按指定字段进行区间范围查询 # 大于等于 .from .gte # 小于等于 .to .lte
//构建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!