How to provide highlighting with Spring data elasticsearch

后端 未结 4 931
死守一世寂寞
死守一世寂寞 2020-12-29 00:11

it seems that SpringData ES don\'t provide classes to fetch highlights returned by ES. Spring Data can return Lists of Objects but the highlights sections in the Json return

4条回答
  •  庸人自扰
    2020-12-29 00:39

    Actually, you could do the following, with a custom ResultExtractor:

    QueryBuilder query = QueryBuilders.matchQuery("name", "tom"); 
    SearchQuery searchQuery = new NativeSearchQueryBuilder()
                               .withQuery(query)
                               .withHighlightFields(new Field("name")).build();
    return elasticsearchTemplate.query(searchQuery.build(), new CustomResultExtractor());
    

    And then

    public class CustomResultExtractor implements ResultsExtractor> {
    
    private final DefaultEntityMapper defaultEntityMapper;
    
    public CustomResultExtractor() {
        defaultEntityMapper = new DefaultEntityMapper();
    }
    
    
    @Override
    public List extract(SearchResponse response) {
        return StreamSupport.stream(response.getHits().spliterator(), false) 
            .map(this::searchHitToMyClass) 
            .collect(Collectors.toList());
    }
    
    private MyClass searchHitToMyClass(SearchHit searchHit) {
        MyElasticSearchObject myObject;
        try {
            myObject = defaultEntityMapper.mapToObject(searchHit.getSourceAsString(), MyElasticSearchObject.class);
        } catch (IOException e) {
            throw new ElasticsearchException("failed to map source [ " + searchHit.getSourceAsString() + "] to class " + MyElasticSearchObject.class.getSimpleName(), e);
        }
        List highlights = searchHit.getHighlightFields().values()
            .stream() 
            .flatMap(highlightField -> Arrays.stream(highlightField.fragments())) 
            .map(Text::string) 
            .collect(Collectors.toList());
        // Or whatever you want to do with the highlights
        return new MyClass(myObject, highlights);
    }}
    

    Note that I used a list but you could use any other iterable data structure. Also, you could do something else with the highlights. Here I'm simply listing them.

提交回复
热议问题