ES检索结果高亮显示JAVA以及Kibana实现

news2024/9/29 10:13:07
/**
 * 查询接口
 *
 * @param searchReqVO
 */
public EsSearchPageInfoResVO guessYouWantListForClient(EsSearchRequestVO searchReqVO) {
    BaseInfo baseInfo = getApp();
    List<Long> catalogues = getAccesses();
    EsSearchPageInfoResVO result = new EsSearchPageInfoResVO();
    SearchRequest request = new SearchRequest();
    CountRequest countRequest = new CountRequest();
    countRequest.indices(INDEX_NAME);
    request.indices(INDEX_NAME);
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    highlightBuilder.preTags("<em style='color: red'>");
    highlightBuilder.postTags("</em>");
    highlightBuilder.field("question_info");
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
    boolQueryBuilder.must(QueryBuilders.matchQuery("base_info_id", baseInfo.getId()));
    int shouldCount = 0;
    if (!StringUtils.isEmpty(searchReqVO.getSearchText())) {
        shouldCount++;
        boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("question_info", searchReqVO.getSearchText()));
        boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("answer_info", searchReqVO.getSearchText()));
        boolQueryBuilder.should(QueryBuilders.matchPhraseQuery("keyword", searchReqVO.getSearchText()));
        boolQueryBuilder.should(QueryBuilders.matchQuery("question_info", searchReqVO.getSearchText()));
        boolQueryBuilder.should(QueryBuilders.matchQuery("answer_info", searchReqVO.getSearchText()));
        boolQueryBuilder.should(QueryBuilders.matchQuery("keyword", searchReqVO.getSearchText()));
    }
    boolQueryBuilder.minimumShouldMatch(shouldCount);
    countRequest.query(boolQueryBuilder);
    //设置分页 from:页码,(当前页-1)*每页条数
    searchSourceBuilder.from(searchReqVO.getRows() * (searchReqVO.getPage() - 1));
    searchSourceBuilder.size(searchReqVO.getRows());
    searchSourceBuilder.query(boolQueryBuilder);
    searchSourceBuilder.highlighter(highlightBuilder);


    //未输入模糊搜索内容时默认按更新时间排序、输入则默认按es相似度分值排序
    if (StringUtils.isEmpty(searchReqVO.getSearchText())) {
        searchSourceBuilder.sort("update_timestamp", SortOrder.DESC);
    }
    request.source(searchSourceBuilder);
    SearchResponse searchResponse = null;
    CountResponse countResponse = null;
    List<EsSearchResponseVO> resultList = new ArrayList<>();
    try {
        countResponse = highLevelClient.count(countRequest, RequestOptions.DEFAULT);
        Long totalCount = countResponse.getCount();
        result.setTotal(totalCount);
        searchResponse = highLevelClient.search(request, RequestOptions.DEFAULT);
        SearchHit[] searchHits = searchResponse.getHits().getHits();
        for (SearchHit searchHit : searchHits) {
            //原理就是用es自动查找出来的hightlight字段值替换正常检索出来的值
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            HighlightField highlightTitle = highlightFields.get("question_info");//注意是数组
            Map<String, Object> sourceMap = searchHit.getSourceAsMap();
            if(highlightTitle != null){
                Text[] fragments = highlightTitle.getFragments();
                if(fragments != null && fragments.length > 0){
                    //替换(fargment[0]是Text类型的)
                    sourceMap.replace("question_info", fragments[0].toString());
                }
            }
            ESQuestionAnswerVersionDTO esResult = JSON.parseObject(JSON.toJSONString(sourceMap), ESQuestionAnswerVersionDTO.class);
            EsSearchResponseVO vo = new EsSearchResponseVO();
            vo.setQuestionInfo(esResult.getQuestion_info());
            vo.setKnowledgeId(esResult.getKnowledge_id());
            vo.setId(esResult.getId());
            vo.setBaseInfoId(esResult.getBase_info_id());
            resultList.add(vo);
        }
    } catch (Exception e) {
        log.info("联想搜索知识失败,搜索条件: ", JSONUtil.toJsonStr(searchReqVO));
        Traces.recordException(e);
    }
    result.setRows(resultList);
    return result;
}

对比做了高亮前后的结果返回:

高亮前:

高亮后:

可以看到加入高亮的代码之后返回的json串命中的关键字被套了一层<em style=‘color: red’>xxx</em>标签,也就是我们前置设置的preTags与postTags;

当然hightlight本身支持多个字段高亮,java代码实现只要设置多个    

highlightBuilder.field("aaaa”);

highlightBuilder.field(“bbb”);

…

后续查询出结果之后挨个全部替换成hightlight的结果即可。


翻译成es的kibana语句如下:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 22.00881,
    "hits" : [
      {
        "_index" : "knowledge_question_answer",
        "_type" : "_doc",
        "_id" : "12494",
        "_score" : 22.00881,
        "_source" : {
          "id" : 12494,
          "question_info" : "香肠/腊肠/金字火腿常见问题",
          "answer_info" : "万有全广式香肠蒸出来口感很粉,&nbsp; 是面粉放多了吗",
          "keyword" : "香肠发酸,香肠,腊肠,金字火腿,火腿,金字金华香肠,腊肠发酸,万有全广式香肠"
        },
        "highlight" : {
          "question_info" : [
            "<em style='color: red'>香肠</em>/腊肠/金字火腿常见问题"
          ]
        }
      }
    ]
  }
}

这里只设置了一个字段高亮,只要该字段有匹配到的关键字就会被放到结果集的高亮那一栏中。结果如下:

GET /knowledge_question_answer/_doc/_search
{
  "from": 0,
  "size": 20,
  "query": {
    "bool": {
      "should": [
        //查询条件忽略
        ...
      ],
      "adjust_pure_negative": true,
      "minimum_should_match": "1",
      "boost": 1
    }
  },
  "highlight": {
    "pre_tags": [
      "<em style='color: red'>"
    ],
    "post_tags": [
      "</em>"
    ],
    "fields": {
      "question_info": {},
      "answer_info": {},
      "keyword": {}
    }
  }
}

多个高亮查询结果如下:

{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 22.00881,
    "hits" : [
      {
        "_index" : "knowledge_question_answer",
        "_type" : "_doc",
        "_id" : "12494",
        "_score" : 22.00881,
        "_source" : {
          "id" : 12494,
          "question_info" : "香肠/腊肠/金字火腿常见问题",
          "answer_info" : "万有全广式香肠蒸出来口感很粉,&nbsp; 是面粉放多了吗",
          "keyword" : "香肠发酸,香肠,腊肠,金字火腿,火腿,金字金华香肠,腊肠发酸,万有全广式香肠"
        },
        "highlight" : {
          "answer_info" : [
"万有全广式<em style='color: red'>香肠</em>蒸出来口感很粉,&nbsp; 是面粉放多了吗?"
          ],
          "question_info" : [
            "<em style='color: red'>香肠</em>/腊肠/金字火腿常见问题"
          ],
          "keyword" : [
            "<em style='color: red'>香肠</em>发酸,<em style='color: red'>香肠</em>,腊肠,金字火腿,火腿,金字金华<em style='color: red'>香肠</em>,腊肠发酸,万有全广式<em style='color: red'>香肠</em>"
          ]
        }
      }
    ]
  }
}

可以看到,多个field只要出现检索词“香肠”的地方 都被套上了前置后置的标签,展示在前端页面也就又了高亮显示的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/789200.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreeRTOS(中断管理)

一、中断定义 中断&#xff08;Interrupt&#xff09;是计算机系统中的一种事件&#xff0c;它打断了正常的程序执行流程&#xff0c;引起处理器&#xff08;CPU&#xff09;暂时转去执行其他任务或处理特殊事件。中断通常由硬件设备或者操作系统产生&#xff0c;用于向处理器传…

PP-YOLOE 论文学习

1. 解决了什么问题&#xff1f; 单阶段目标检测器能很好地平衡速度和精度&#xff0c;YOLO 系列是其中的代表。YOLOX 采用了 anchor-free 范式&#xff0c;加入了动态标签分配以提升检测表现&#xff0c;在 Tesla V100 上取得了 50.1 mAP&#xff0c;速度是 68.9 FPS。本文提出…

了解uuid

目录 一.认识 UUID 二.UUID 会耗尽吗 三.UUID 会重复吗 四.UUID 的版本 五.UUID的应用 六.java 如何生成UUID 一.认识 UUID uuid是经过特定的算法得到的. UUID 是 16 字节 128 位长的数字&#xff0c;通常以 36 字节的字符串表示&#xff0c;示例如下&#xff1a; 3F2…

大模型,开源干不掉闭源

开源大模型对闭源大模型的冲击&#xff0c;变得非常猛烈。 今年3月&#xff0c;Meta发布了Llama&#xff08;羊驼&#xff09;&#xff0c;很快成为AI社区内最强大的开源大模型&#xff0c;也是许多模型的基座模型。有人戏称&#xff0c;当前的大模型集群&#xff0c;就是一堆各…

c++一级 输入三个数,按照从小到大的顺序输出

这个题是2022年9月份c一级的真题&#xff0c;它说难不难&#xff0c;说不难也难&#xff0c;评判标准主要看学生学到哪种程度以及 使用的是哪种方法。 首先来看用最基础的判断怎么做&#xff1a; #include<iostream> using namespace std; int main(){int a,b,c;cin>…

macOS Ventura 13.5 (22G74) 正式版发布,ISO、IPSW、PKG 下载

macOS Ventura 13.5 (22G74) 正式版发布&#xff0c;ISO、IPSW、PKG 下载 本站下载的 macOS Ventura 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也…

Cesium态势标绘专题-正三角形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

Cesium态势标绘专题-弓形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

opencv-17 脸部打码及解码

使用掩模和按位运算方式实现的对脸部打码、解码实例 代码如下&#xff1a; import cv2 import numpy as np #读取原始载体图像 lenacv2.imread("lena.png",0) #读取原始载体图像的 shape 值 r,clena.shape masknp.zeros((r,c),dtypenp.uint8) mask[220:400,250:350…

UE虚幻引擎教程_生成云平台指定路径下的exe文件

市面上大量优秀的游戏都是基于UE制作的&#xff0c;UE虚幻引擎制作的作品可以在windows、mac、linux以及ps4、x-boxone、ios、android甚至是html5等平台上运行。本文介绍了UE虚幻引擎如何生成云平台指定路径下的EXE。 一、云平台会运行打包文件夹下指定路径的EXE文件 但有时候…

spring6——概述

文章目录 概述Spring 是什么&#xff1f;Spring 的狭义与广义Spring Framework特点Spring模块组成 概述 Spring 是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 J…

数据可视化(2)

1.柱状图 #柱状图 #bar(x,height,width,*,aligncenter,**kwargs) #height柱子的高度&#xff0c;即y轴上的数据 #width数组的宽度&#xff0c;默认值0.8 #*表示后面的参数为匿名关键字&#xff0c;必须传入参数 #kwargs关键字参数x[1,2,3,4,5] height[random.randint(10,100)f…

智融SW3518S降压协议IC一款适合车充控制芯片

描述 SW3518S 是一款高集成度的多快充协议双口充电芯片&#xff0c; 支持 AC 口任意口快充输出&#xff0c; 支持双口独立限流。 其集成了 5A 高效率同步降压变换器&#xff0c; 支持 PPS/PD/QC/AFC/FCP/SCP/PE/SFCP/VOOC等多种快充协议&#xff0c; 最大输出 PD 100W&#xff…

在 vue3 中使用 ScrollReveal

文章目录 什么是 ScrollReveal安装使用介绍 什么是 ScrollReveal ScrollReveal 官网链接&#xff1a;https://scrollrevealjs.org/ ScrollReveal 是一个 JavaScript 库&#xff0c;用于在元素进入/离开视口时轻松实现动画效果。 先看个入门示例&#xff1a; ScrollReveal …

mac brew安装 node 踩坑日记- n切换node不生效

最近用了一个旧电脑开发&#xff0c;发现里面node管理混乱&#xff0c;有nvm、n和homebrew&#xff0c;导致切换node 切换不了&#xff0c;开发也有莫名其妙的错误。所以我打算重新装一下node&#xff0c;使用n做为管理工具。 1. 删除nvm cd ~ rm -rf .nvm2. 删除n sudo rm -…

HarmonyOS/OpenHarmony元服务开发-创建一个ArkTS卡片

在已有的应用工程中&#xff0c;创建ArkTS卡片&#xff0c;具体操作方式如下。 1.创建卡片。 2.根据实际业务场景&#xff0c;选择一个卡片模板。 3.在选择卡片的开发语言类型&#xff08;Language&#xff09;时&#xff0c;选择ArkTS选项&#xff0c;然后单击“Finish”&…

【RS】基于规则的面向对象分类

ENVI使用最多的工具就是分类&#xff0c;这也是很多卫星影像的用途。在ENVI中有很多分类工具&#xff0c;如最基础的监督分类&#xff08;最大似然法、最小距离、支持向量机、随机森林&#xff09;、非监督分类&#xff08;K-means、IsoData&#xff09;&#xff0c;还有面向对…

sqlserver 复制数据库数据

sqlserver 建立索引 alter table [dbo].[SYS_MQTT_MESSAGE_LOG_1] add constraint pk0230725 primary key (smml_id) 主键 建聚集索引 其他的字段要和排序字段一起建索引

家政服务小程序制作攻略揭秘

想要打造一个家政服务小程序&#xff0c;但是又不懂编程和设计&#xff1f;不用担心&#xff01;下面将为你详细介绍如何利用第三方平台&#xff0c;从零开始打造一个家政服务小程序。 首先&#xff0c;你需要找到一个适合的第三方平台&#xff0c;例如乔拓云网。在乔拓云网的【…

2023年Q2京东小家电市场数据分析(京东数据运营)

伴随人们对生活品质追求的提高&#xff0c;以及拥有新兴消费理念的年轻人逐渐成为消费主力&#xff0c;功能新潮、外观精致的小家电经常在电商平台销售榜单里“榜上有名”。本期我们便一起来分析Q2京东小家电市场中&#xff0c;一些较为热门的精致生活小电的行业大盘变动情况。…