一、功能需求

当我们用ES查询到结果后,想对命中关键词的实体的多个字段自动高亮,应该如何实现呢?

需要实现这个功能,大概分为以下几个步骤:

二、实现步骤

  1. 构造查询方法,设置高亮(SearchHits方法)

    /*** 查询条件构造方法** @param indices 索引名称(需要从那个索引当中查询)* @param req     查询条件* @param fields  查询的文档(对应数据库的字段)* @return SearchHit*/public SearchHits queryBuilder(String indices, SearchREQ req, String[] fields) throws IOException {SearchSourceBuilder builder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();HighlightBuilder highlightBuilder = new HighlightBuilder();//设置分页if (req.getCurrent() > 0) {builder.from((int) req.getCurrent());}if (req.getSize() > 0) {builder.size((int) req.getSize());}//设置高亮highlightBuilder.field("*"); //所有的字段都高亮highlightBuilder.requireFieldMatch(false);//如果要多个字段高亮,这项要为falsehighlightBuilder.preTags("<font color='red'>").postTags("</font'>").fragmentSize(800000)//下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等;  最大高亮分片数.numOfFragments(0);//从第一个分片获取高亮片段builder.highlighter(highlightBuilder);//构建查询条件if (StringUtils.isNotEmpty(req.getUserId())) {boolQueryBuilder.must(QueryBuilders.matchQuery("userId", req.getUserId()));}//模糊查询boolQueryBuilder.should(QueryBuilders.multiMatchQuery("*" + req.getText() + "*", fields));//对查询结果进行排序builder.query(boolQueryBuilder).sort("createDate", SortOrder.DESC);SearchRequest searchRequest = new SearchRequest(indices);searchRequest.source(builder);SearchResponse searchResponse = levelClientTests.search(searchRequest, RequestOptions.DEFAULT);return searchResponse.getHits();}
  2. 调用查询方法,查询结果(findObject方法)

    public Result findObject(SearchREQ req) throws IOException, NoSuchFieldException {if (StringUtils.isEmpty(req.getText())) {return Result.error("查找内容不能为空");}List<Object> resultList = null;Map<Object, Object> resultMap = new HashMap<>();SearchHits hits;String indices = "mcb_article";String[] fields = {"summary", "title", "mdContent"};hits = queryBuilder(indices, req, fields);Article article = null;resultList = new ArrayList<>();//遍历查询结果并接收for (SearchHit searchHit : hits) {article = (Article) replaceAttr(searchHit, fields, indices);if (article != null) {resultList.add(article);}}}
    
  3. 使用工具替换实体的属性值(replaceAttr方法)

    /*** 替换高亮属性** @param searchHit 查询结果* @param attrs 字段名* @return* @throws JsonProcessingException* @throws NoSuchFieldException*/private Object replaceAttr(SearchHit searchHit, String[] attrs) throws JsonProcessingException, NoSuchFieldException {ObjectMapper objectMapper = new ObjectMapper();EntityUtil util = new EntityUtil();Object o = null;Article article = new Article();for (String field : attrs) {Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();HighlightField hField = highlightFields.get(field);if (hField != null) {//替换高亮字段Text[] fragments = hField.fragments();StringBuilder text = new StringBuilder();for (Text textGet : fragments) {text.append(textGet);}//对象的值只能读一次,否则会被覆盖if (article.getId() == null) {article = objectMapper.readValue(searchHit.getSourceAsString(), article.getClass());}//设置对象的属性值util.setValue(article, Article.class,field,Article.class.getDeclaredField(field).getType(),text.toString());o = article;continue;}}return o;}
    
  4. 设置对象的属性值()

    
    /*** 实体工具* @author MyLover* @date 2022.2.6* @version 1.0.0*/
    public class EntityUtil {/*** 设置对象对应的属性值* @param obj 传入的对象* @param clazz 传入对象的类* @param filedName 需要设置的字段名* @param typeClass 字段的类型* @param value 需要设置的值*  实例:  设置Article的id属性值为1*  Article article = new Article();*  String field = "id";*  setValue(article_es1,Article_ES.class,field,*  Article.class.getDeclaredField(field).getType(),"1");*/public void setValue(Object obj, Class<?> clazz, String filedName, Class<?> typeClass, Object value) {String methodName = "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);try {Method method = clazz.getDeclaredMethod(methodName, typeClass);method.invoke(obj, getClassTypeValue(typeClass, value));} catch (Exception ex) {ex.printStackTrace();}}/*** 根据属性,获取对象的属性值, 例如: getGetMethod(Article,id)* @param ob   对象* @param name 属性名*/public  Object getGetMethod(Object ob, String name) throws Exception {Method[] m = ob.getClass().getMethods();for (Method method : m) {if (("get" + name).toLowerCase().equals(method.getName().toLowerCase())) {return method.invoke(ob);}}return null;}private  Object getClassTypeValue(Class<?> typeClass, Object value) {if (typeClass == int.class || value instanceof Integer) {if (null == value) {return 0;}return value;} else if (typeClass == short.class) {if (null == value) {return 0;}return value;} else if (typeClass == byte.class) {if (null == value) {return 0;}return value;} else if (typeClass == double.class) {if (null == value) {return 0;}return value;} else if (typeClass == long.class) {if (null == value) {return 0;}return value;} else if (typeClass == String.class) {if (null == value) {return "";}return value;} else if (typeClass == boolean.class) {if (null == value) {return true;}return value;} else if (typeClass == BigDecimal.class) {if (null == value) {return new BigDecimal(0);}return new BigDecimal(value + "");} else {return typeClass.cast(value);}}
    }
    

ES查询结果全局高亮相关推荐

  1. ES(三)es查询语法

    一.介绍:语法GET /索引/类型/_search         查询条件,这个查询条件有两种写法, 一种是在GET的url中指定参数:这种方法比较简单,如查询所有 GET /wtyy-test/u ...

  2. es查询-统计总数以及深度分页

    一.查询总数 1.  ES 查询 hits 统计总数不准? 当我们使用 ES 的时候,有时会比较关心匹配到的文档总数是多少,所以在查询得到结果后会使用 hits.total.value 这个值作为匹配 ...

  3. docker安装es+mac安装Kibana工具+es查询语法笔记

    一.docker安装es 1.下载镜像 docker pull elasticsearch:7.9.0 下载完后,查看镜像 docker images ​​ 2.启动镜像 docker network ...

  4. ElasticSearch使用(嵌套查询、嵌套高亮)

    ElasticSearch使用(嵌套查询.嵌套高亮) 嵌套查询 bool 查询 must.should关系 1.只有must 2.只有should 3.must和should同时存在 4.怎样设置sh ...

  5. 【236期】ElasticSearch 进阶:一文全览各种 ES 查询在 Java 中的实现

    点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...

  6. php拉查询封装,对Elasticsearch-PHP进行查询语句封装 可实现链式调用 方便 es查询...

    elasticsearch-build-query 对Elasticsearch-PHP进行查询语句封装 可实现链式调用 方便 es查询 Installation via Composer The r ...

  7. java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。

    java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制. 一.为什么要使用ES的scroll (1)首先我们要明白es的查询机制:ES的搜索是分2个阶段进行的,即Que ...

  8. ES 查询数据的工作原理是什么?

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | http://8rr.co/GsAa 面试题 ...

  9. es查询语句拼接 java_JAVA使用ElasticSearch查询in和not in的实现方式

    JAVA使用ElasticSearch查询in和not in的实现方式 发布时间:2020-08-22 16:03:11 来源:脚本之家 阅读:119 作者:执笔记忆的空白 ElasticSearch ...

  10. es 删除数据_es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?...

    面试题 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗? 面试官心理分析 问这个,其实面试官就是要看看你了解不了解 es 的一些基 ...

最新文章

  1. 使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒
  2. 如何利用隐写术配合四个重定向连接到C2服务器
  3. java blender_[转载]将Blender模型展示于WEB
  4. 一条SQL语句的执行过程
  5. Ext.Net全部Icon图标名称展示
  6. 如何解决多机房、多网络下的物联网部署方案?
  7. XMLHttpRequest对象AJAX技术的基本使用
  8. Windows下用C语言连接Mysql注意问题
  9. python正则表达式(1)--特殊字符
  10. Markdown 标记语言指北
  11. 无共享模式的数据架构
  12. cad文件管理服务器,CAD文件管理(ZT)
  13. matlab hspice联合仿真,HSPICE TOOLBOX FOR MATLAB
  14. 软件测试工程师晋升通道
  15. 水的智慧:孔子、老子、禅语 人生处世当如水,善待一切
  16. 常用的手机宽度 前端切图用 常用的手机尺寸
  17. 000001历史数据_上证指数(000001) 的历史行情2000
  18. android 窗口圆角
  19. 开箱即用的物联网平台-IoTLink
  20. 基于开源SATA核的PCIE-SATA设计

热门文章

  1. python 判断健在循环字典的第几层_2.关于python的if判断,循环总结。
  2. 生成PDF文件的几种方法
  3. php程序员工作日记,PHP程序员战地日记
  4. python做问卷调查赚钱的软件_在网上做调查问卷能挣钱吗?靠谱吗
  5. 女朋友让我深夜十二点催她睡觉,我有Python我就不干
  6. 计算机信息管理调查报告模板,精选市场调查报告模板锦集九篇
  7. 网站实现GNSS数据批量下载
  8. 马化腾教你做产品:改掉这七点,让产品自己说话
  9. 【名企招聘】4月26日19点,涛思数据带着高薪岗位JD和精美周边来啦~
  10. html全局背景代码,html背景代码