spring-data-elasticseach高亮代码

spring-data-elasticseach高亮代码

  •  7个月前
  •  386
  •  Java Elasticsearch 

使用spring-data-elasticsearch查询时,设置了代码高亮,但是怎么都获取不到高亮的结果。

找到StackOverflow上的一个回答: https://stackoverflow.com/questions/37049764/how-to-provide-highlighting-with-spring-data-elasticsearch

但是这个方案对我没用,应该是版本问题,但是给我了很大启发。

思路:

1、实现自定义的ResultMapper继承DefaultResultMapper

2、重写mapResults方法

3、获取SearchHit中的sourcsAsMap和highlightFields,使用highlightFileds中的高亮后的字段值暴力替换掉sourcsAsMap中未高亮的值


先把主要的代码贴出来,以后再做完善。

自定义ResultMapper

public class HighlightResultMapper extends DefaultResultMapper {

    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
        for (SearchHit hit : response.getHits()) {
            Map<String, Object> sourceMap = hit.getSourceAsMap();
            for (Map.Entry<String, HighlightField> entry : hit.getHighlightFields().entrySet()) {
                String key = entry.getKey();
                if (sourceMap.containsKey(key)) {
                    Text[] fragments = entry.getValue().getFragments();
                    sourceMap.put(key, transTextArrayToString(fragments));
                }
            }
            hit.sourceRef(new ByteBufferReference(ByteBuffer.wrap(JSONObject.toJSONString(sourceMap).getBytes())));
        }
        return super.mapResults(response, clazz, pageable);
    }

    private String transTextArrayToString(Text[] fragments) {
        if (null == fragments) return "";
        StringBuffer buffer = new StringBuffer();
        for (Text fragment : fragments) {
            buffer.append(fragment.string());
        }
        return buffer.toString();
    }

}

使用方式

@Test
public void highlightTest() {
    MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("message", "信用卡");
    HighlightBuilder.Field message = new HighlightBuilder.Field("message").preTags("<em>").postTags("</em>");
    Pageable of = PageRequest.of(0, 1);
    NativeSearchQuery query = new NativeSearchQueryBuilder()
            .withQuery(matchQueryBuilder)
            .withHighlightFields(message)
            .withPageable(of)
            .build();

    Page<ESThreadEntity> esThreadEntities = elasticsearchRestTemplate.queryForPage(query, ESThreadEntity.class, new HighlightResultMapper());
    esThreadEntities.get().forEach(System.out::println);
}

结果

招行国航知音<em>信用卡</em> 招行Young卡 招行双币<em>信用卡</em> 招行三星<em>信用卡</em>

虽然比较暴力,但还是好使的。


扫一扫分享到微信

已有 条评论
写评论