当前位置: 首页 > article >正文

Java结合ElasticSearch根据查询关键字,高亮显示全文数据。

由于es高亮显示机制的问题。当全文内容过多,且搜索中标又少时,就会出现高亮结果无法覆盖全文。因此需要根据需求手动替换。
1.根据es的ik分词器获取搜索词的分词结果。
es部分:

//中文分词解析
post /_analyze
{
    "analyzer":"ik_smart",
    "text":"谷歌浏览器"
}

//结果
{
    "tokens": [
        {
            "token": "谷歌",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "浏览器",
            "start_offset": 2,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

注意:ik_smart 是最粗颗粒度,不会有重复分词。ik_max_word 是最细颗粒度,会有重复分词。高亮显示只需要最粗即可。
ik_smart:
在这里插入图片描述
ik_max_word:
在这里插入图片描述

将es的语句转为Java语句:

//主要使用的包
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;


    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * 获取到es的分词结果
     *
     * @param searchContent 查询关键字
     * @return 分词结果
     */
    private List<String> getAnalyze(String searchContent) {
        List<String> tokens = new ArrayList<>();
        if (StringUtils.isNotEmpty(searchContent)) {
            String endpoint = "/_analyze";
            String body = "{\n" +
                    "  \"analyzer\": \"ik_smart\",\n" +
                    "  \"text\": \"" + searchContent + "\"\n" +
                    "}";
            try {
                Request request = new Request("POST", endpoint);
                request.setJsonEntity(body);
                Response response = restHighLevelClient.getLowLevelClient().performRequest(request);
                InputStream content = response.getEntity().getContent();
                JsonNode jsonNode = objectMapper.readTree(content);
                if (jsonNode.has("tokens")) {
                    for (JsonNode token : jsonNode.get("tokens")) {
                        tokens.add(token.get("token").asText());
                    }
                }
            } catch (IOException | UnsupportedOperationException e) {
                log.error("ES查询分词异常", e);
            }
        }
        return tokens;
    }

2.根据获取到的多个分词数据。替换全文内容。

    /**
     * 根据多个需要替换的字符,高效替换全文数据
     * @param replaceStrList 替换字符
     * @param content 全文
     * @return 高亮显示的全文
     */
    private String replaceHighlight(List<String> replaceStrList, String content) {
        StringBuffer result = new StringBuffer();
        try {
            Map<String, String> replacements = new HashMap<>();
            for (String replaceStr : replaceStrList) {
                replacements.put(replaceStr, "<font class='eslight'>" + replaceStr + "</font>");
            }
            Pattern pattern = Pattern.compile(String.join("|", replacements.keySet()));
            Matcher matcher = pattern.matcher(content);

            while (matcher.find()) {
                matcher.appendReplacement(result, replacements.get(matcher.group(0)));
            }
            matcher.appendTail(result);
        } catch (Exception e) {
            log.error("替换高亮显示异常", e);
        }
        return result.toString();
    }

此时就能将全文关键词以分词的效果高亮显示了。


http://www.kler.cn/a/395022.html

相关文章:

  • 学习threejs,THREE.PlaneGeometry 二维平面几何体
  • idea设置控制台日志输出自动换行
  • 顶顶通呼叫中心中间件mod_cti模块安全增强,预防盗打风险(mod_cti基于FreeSWITCH)
  • VIVO Android面试题及参考答案
  • 如何解决 ‘adb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题
  • VSCode:IDE显示设置 --自定义字体及主题颜色
  • 20241114软考架构-------软考案例15答案
  • MQ集群
  • Intellij idea 报错:Error : java 不支持发行版本5
  • 华为数字化转型的本质为何是管理变革
  • PostgreSql - 字符串函数
  • 综合文化信息管理系统|基于java和小程序的综合文化信息管理系统设计与实现(源码+数据库+文档)
  • 双层for循环嵌套式(day12)
  • Docker构建禅道项目管理系统
  • 【Electron】总结:如何创建Electron+Element Plus的项目
  • 游戏引擎中LOD渲染技术
  • NeurIPS2024论文分享┆HyperPrism:一种针对非独立同分布数据和时变通信链路的分布式机器学习自适应非线性聚合框架
  • 游戏引擎学习第10天
  • 酒店行业数据仓库
  • TofuAI处理BT1120时序视频要求
  • 11.14 机器学习-朴素贝叶斯+决策树算法
  • Mysql ACID实现原理
  • 链表(Linkedlist)
  • 实验二:Docker存储配置与管理
  • 简易的学生信息管理系统制作——C语言实现
  • STM32CubeMX学习笔记33---芯片因未选serial debug被锁住