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

ElasticSearch JavaRestClient查询之高亮显示

文章目录

    • 一、高亮核心概念
    • 二、高亮请求构建
      • 1. API结构
      • 2. 完整构建示例
      • 3. 简化写法
    • 三、高亮结果解析
      • 1. 解析流程
      • 2. 多片段处理
    • 四、完整案例实现
      • 需求说明:
      • Java代码实现:
    • 五、关键注意事项
      • 1. 字段类型要求
      • 2. 搜索结果要求
      • 3. 性能优化
    • 六、常见问题排查
      • 1. 高亮结果为空
      • 2. 标签未生效
      • 3. 多字段高亮
    • 七、扩展功能
      • 1. 多种高亮类型
      • 2. 匹配片段控制
      • 3. 全局标签设置

一、高亮核心概念

  1. 高亮结果与原始数据分离:
    • _source:原始文档数据(无高亮)
    • highlight:独立的高亮结果字段(带HTML标签)
  2. 高亮三要素:
    • 高亮字段(必须与查询字段一致)
    • 前置标签(默认<em>
    • 后置标签(默认</em>

二、高亮请求构建

1. API结构

SearchRequest request = new SearchRequest("index");
request.source()
    .query(...)        // 必须包含搜索条件
    .highlighter(...); // 设置高亮参数

2. 完整构建示例

// 创建高亮构建器
HighlightBuilder highlightBuilder = new HighlightBuilder();

// 设置高亮字段与标签
highlightBuilder.field("name")             // 高亮字段
    .preTags("<em>")                      // 前置标签
    .postTags("</em>");                   // 后置标签

// 加入请求
request.source().highlighter(highlightBuilder);

3. 简化写法

request.source().highlighter(
    new HighlightBuilder()
        .field(new HighlightBuilder.Field("name")
            .preTags("<strong>")
            .postTags("</strong>"))
);

三、高亮结果解析

1. 解析流程

SearchHits hits = response.getHits();
for (SearchHit hit : hits) {
    // 1. 获取原始数据
    String sourceJson = hit.getSourceAsString();
    HotelDoc doc = JSON.parseObject(sourceJson, HotelDoc.class);
    
    // 2. 获取高亮数据
    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
    if (highlightFields.containsKey("name")) {
        // 3. 提取高亮片段
        HighlightField highlightField = highlightFields.get("name");
        Text[] fragments = highlightField.getFragments();
        String highlightedName = fragments[0].string();
        
        // 4. 替换原始数据
        doc.setName(highlightedName);
    }
}

2. 多片段处理

// 拼接所有高亮片段
StringBuilder highlightedText = new StringBuilder();
for (Text fragment : fragments) {
    highlightedText.append(fragment.string());
}
doc.setName(highlightedText.toString());

四、完整案例实现

需求说明:

  • 搜索"脱脂牛奶"
  • name字段进行高亮
  • 使用自定义标签<em></em>

Java代码实现:

@Test
void testHighlight() throws IOException {
// 1. 创建请求对象
SearchRequest request = new SearchRequest("items");

// 2. 构建查询条件
request.source().query(QueryBuilders.matchQuery("name", "脱脂牛奶"));

// 3. 设置高亮参数
HighlightBuilder highlightBuilder = new HighlightBuilder()
.field("name")
.preTags("<em>")
.postTags("</em>");
request.source().highlighter(highlightBuilder);

// 4. 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);

// 5. 解析结果
parseHighlightResponse(response);
}

private void parseHighlightResponse(SearchResponse response) {
    SearchHits hits = response.getHits();
    for (SearchHit hit : hits) {
        // 解析原始数据
        ItemDoc doc = JSONUtil.toBean(hit.getSourceAsString(), ItemDoc.class);

        // 处理高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (!highlightFields.isEmpty()) {
            HighlightField nameField = highlightFields.get("name");
            if (nameField != null) {
                String highlightedName = nameField.getFragments()[0].string();
                doc.setName(highlightedName);
            }
        }

        System.out.println(doc);
    }
}

运行结果:

五、关键注意事项

1. 字段类型要求

  • 高亮字段必须是text类型且包含keyword子字段
  • 错误配置会导致无法获取高亮结果

2. 搜索结果要求

  • 必须包含实际搜索条件(如match查询),否则无高亮结果

3. 性能优化

  • 避免对长文本字段进行高亮(如content字段)
  • 设置fragment_size控制返回片段长度:
highlightBuilder.field("name").fragmentSize(200);

六、常见问题排查

1. 高亮结果为空

  • 检查查询条件是否实际匹配文档
  • 验证字段映射是否支持高亮
  • 检查高亮字段名是否与查询字段一致

2. 标签未生效

  • 确认前端HTML转义处理(防止XSS攻击)
  • 检查标签是否被CSS样式覆盖

3. 多字段高亮

// 同时高亮多个字段
highlightBuilder
    .field("title")
    .field("description");

七、扩展功能

1. 多种高亮类型

// 使用不同的高亮器
highlightBuilder
    .highlighterType("unified")  // 默认高亮器
    .highlighterType("plain");   // 简单高亮器

2. 匹配片段控制

highlightBuilder
    .numOfFragments(3)       // 返回最多3个片段
    .noMatchSize(100);       // 无匹配时返回前100字符

3. 全局标签设置

// 设置所有字段的默认标签
highlightBuilder
    .preTags("<strong>")
    .postTags("</strong>");
http://www.dtcms.com/a/111227.html

相关文章:

  • JS用ES6和ES5分别实现:8字节长整数和字节数组的互转
  • 软考系统架构师 — 4 嵌入式软件
  • H.266/VVC SCC技术学习:块差分脉冲编码调整(block differential pulse coded modulation, BDPCM)
  • 生信入门:专栏概要与内容目录
  • AI算法大全初见面
  • Redisson使用详解
  • 《Maven高级应用:继承聚合设计与私服Nexus实战指南》
  • 嵌入式学习笔记——SPI协议
  • “一路有你”公益行携手《东方星动》走进湖南岳阳岑川镇中心小学
  • AI Agent设计模式二:Parallelization
  • 【新能源汽车整车动力学模型深度解析:面向MATLAB/Simulink仿真测试工程师的硬核指南】
  • PyTorch:解锁AI新时代的钥匙
  • Python基于时间序列分析的降雨量预测系统的设计与实现【附源码、文档说明】
  • 一周学会Pandas2 Python数据处理与分析-Jupyter Notebook安装
  • C++类的特殊成员函数:构造、拷贝构造与析构函数详解
  • F#语言的折线图
  • Prolog语言的强化学习
  • MySQL 知识点详解(索引、存储引擎、事务、锁机制、优化)
  • 当机器学习遇见购物车分析:FP-Growth算法全解析
  • 对模板方法模式的理解
  • WPF设计学习记录滴滴滴6
  • 池化技术的深度解析与实践指南【大模型总结】
  • 【51单片机】2-6【I/O口】电动车简易防盗报警器实现
  • Python循环控制语句
  • 幻觉抵抗优化大模型:teapotllm
  • Linux 线程1-线程的概念、线程与进程区别、线程的创建、线程的调度机制、线程函数传参
  • SpringBoot+Spring+MyBatis相关知识点
  • MQL5教程 05 指标开发实战:双色线、双线变色MACD、跨时间周期均线
  • TSMaster在新能源汽车研发测试中的硬核应用指南
  • 【rockchip】使用RKMPP+RGA解码H264并转换数据格式输出