ES 加入高亮设置

发布于:2025-03-26 ⋅ 阅读:(18) ⋅ 点赞:(0)


 


searchTextQueryOne = new MatchQuery.Builder().field(searchFieldOne).query(searchText).build();

                    // 帮助中心文档切分 只查询6条
                    Integer finalTopK = 10;
                    List<String> newReturnFileds = returnFields;
                    newReturnFileds.add("kid"); // 需要返回kid

                    Highlight highlight = new Highlight.Builder()
                            .fields("content_answer", new HighlightField.Builder().preTags("<em style='color:red'>").postTags("</em>").build())
                            .requireFieldMatch(false) // 跨字段高亮
                            .build();

                    response = client.search(s -> s
                                    .index(aliasName)
                                    .query(boolQuery._toQuery())
                                    .source(SourceConfig.of(sf -> sf.filter(f -> f.includes(newReturnFileds))))
                                    .highlight(highlight) // 添加高亮
                                    .size(finalTopK),
                            ObjectNode.class);


返回结果的处理

// 检查是否有高亮内容
                            if (hit.highlight() != null && hit.highlight().containsKey("content_answer")) {
                                List<String> highlightedContent = hit.highlight().get("content_answer");

                                // 拼接高亮内容到原始 contentAnswer
                                String highlightedAnswer = String.join(" ", highlightedContent); // 高亮片段拼接
                                String fullAnswer = contentAnswer.replaceFirst(
                                        Pattern.quote(question), // 匹配原始查询关键字
                                        highlightedAnswer          // 替换为高亮内容
                                );

                                // 设置拼接后的高亮内容到 question1
                                question1.setAnswer(fullAnswer);
                            } else {
                                // 如果没有高亮内容,直接设置原始 contentAnswer
                                question1.setAnswer(contentAnswer);
                            }

关键点说明

  1. requireFieldMatch(false)
    这是实现跨字段高亮的关键设置,允许在 content_answer 字段上高亮,即使查询的是其他字段(如 question 字段)

  2. 其他可选参数

    • fragmentSize() - 控制每个高亮片段的大小

    • numOfFragments() - 控制返回的高亮片段数量

    • noMatchSize() - 当没有匹配时返回的文本长度



       

      // 例子
      
      Highlight highlight = new Highlight.Builder()
          .fields(
              new HighlightField.Builder("content_answer")
                  .preTags("<em style='color:red'>")
                  .postTags("</em>")
                  .requireFieldMatch(false)  // 关键设置
                  .fragmentSize(150)        // 可选:设置片段大小
                  .numOfFragments(3)       // 可选:设置片段数量
                  .build()
          )
          .build();
      
      
      SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
          .query(QueryBuilders.matchQuery("question", "搜索词"))  // 搜索question字段
          .highlighter(highlight);
      
      SearchRequest searchRequest = new SearchRequest("your_index")
          .source(searchSourceBuilder);
      
      SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
      
      
      注意事项
      确保 content_answer 字段是 text 类型并且可搜索
      
      对于大型富文本内容,适当增加 fragmentSize 值
      
      如果高亮结果不理想,可以尝试不同的高亮类型:
      
      java
      复制
      .highlighterType("fvh")  // 快速向量高亮器