ES查询结果全局高亮
一、功能需求
当我们用ES查询到结果后,想对命中关键词的实体的多个字段自动高亮,应该如何实现呢?
需要实现这个功能,大概分为以下几个步骤:
二、实现步骤
构造查询方法,设置高亮(
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();}
调用查询方法,查询结果(
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);}}}
使用工具替换实体的属性值(
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;}
设置对象的属性值()
/*** 实体工具* @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查询结果全局高亮相关推荐
- ES(三)es查询语法
一.介绍:语法GET /索引/类型/_search 查询条件,这个查询条件有两种写法, 一种是在GET的url中指定参数:这种方法比较简单,如查询所有 GET /wtyy-test/u ...
- es查询-统计总数以及深度分页
一.查询总数 1. ES 查询 hits 统计总数不准? 当我们使用 ES 的时候,有时会比较关心匹配到的文档总数是多少,所以在查询得到结果后会使用 hits.total.value 这个值作为匹配 ...
- docker安装es+mac安装Kibana工具+es查询语法笔记
一.docker安装es 1.下载镜像 docker pull elasticsearch:7.9.0 下载完后,查看镜像 docker images 2.启动镜像 docker network ...
- ElasticSearch使用(嵌套查询、嵌套高亮)
ElasticSearch使用(嵌套查询.嵌套高亮) 嵌套查询 bool 查询 must.should关系 1.只有must 2.只有should 3.must和should同时存在 4.怎样设置sh ...
- 【236期】ElasticSearch 进阶:一文全览各种 ES 查询在 Java 中的实现
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...
- php拉查询封装,对Elasticsearch-PHP进行查询语句封装 可实现链式调用 方便 es查询...
elasticsearch-build-query 对Elasticsearch-PHP进行查询语句封装 可实现链式调用 方便 es查询 Installation via Composer The r ...
- java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制。
java使用ElasticSearch的scroll查询,高效的解决es查询数量的限制. 一.为什么要使用ES的scroll (1)首先我们要明白es的查询机制:ES的搜索是分2个阶段进行的,即Que ...
- ES 查询数据的工作原理是什么?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | http://8rr.co/GsAa 面试题 ...
- es查询语句拼接 java_JAVA使用ElasticSearch查询in和not in的实现方式
JAVA使用ElasticSearch查询in和not in的实现方式 发布时间:2020-08-22 16:03:11 来源:脚本之家 阅读:119 作者:执笔记忆的空白 ElasticSearch ...
- es 删除数据_es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?...
面试题 es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗? 面试官心理分析 问这个,其实面试官就是要看看你了解不了解 es 的一些基 ...
最新文章
- 使用joda-time工具类 计算时间相差多少 天,小时,分钟,秒
- 如何利用隐写术配合四个重定向连接到C2服务器
- java blender_[转载]将Blender模型展示于WEB
- 一条SQL语句的执行过程
- Ext.Net全部Icon图标名称展示
- 如何解决多机房、多网络下的物联网部署方案?
- XMLHttpRequest对象AJAX技术的基本使用
- Windows下用C语言连接Mysql注意问题
- python正则表达式(1)--特殊字符
- Markdown 标记语言指北
- 无共享模式的数据架构
- cad文件管理服务器,CAD文件管理(ZT)
- matlab hspice联合仿真,HSPICE TOOLBOX FOR MATLAB
- 软件测试工程师晋升通道
- 水的智慧:孔子、老子、禅语 人生处世当如水,善待一切
- 常用的手机宽度 前端切图用 常用的手机尺寸
- 000001历史数据_上证指数(000001) 的历史行情2000
- android 窗口圆角
- 开箱即用的物联网平台-IoTLink
- 基于开源SATA核的PCIE-SATA设计
热门文章
- python 判断健在循环字典的第几层_2.关于python的if判断,循环总结。
- 生成PDF文件的几种方法
- php程序员工作日记,PHP程序员战地日记
- python做问卷调查赚钱的软件_在网上做调查问卷能挣钱吗?靠谱吗
- 女朋友让我深夜十二点催她睡觉,我有Python我就不干
- 计算机信息管理调查报告模板,精选市场调查报告模板锦集九篇
- 网站实现GNSS数据批量下载
- 马化腾教你做产品:改掉这七点,让产品自己说话
- 【名企招聘】4月26日19点,涛思数据带着高薪岗位JD和精美周边来啦~
- html全局背景代码,html背景代码