ElasticSearch实战(四) 匹配查询、高亮显示

接下来处理模糊查询功能

  • 匹配查询

 修改controller代码,如果传入的keyword不是空值,则改为使用匹配查询

    @RequestMapping("/blogs")
    public String query(Model model, String keyword, Integer pageNum, Integer pageSize) {

        if(pageNum == null || pageNum <= 0)
            pageNum = 1;
        if(pageSize == null || pageSize <= 0)
            pageSize = 5;

        SearchQuery searchQuery = null;
        if (StringUtils.isNotBlank(keyword)) {
            searchQuery = new NativeSearchQueryBuilder()
                    .withPageable(new QPageRequest(pageNum - 1, pageSize))
                    .withQuery(QueryBuilders.multiMatchQuery(keyword, "text", "author"))
                    .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
                    .build();
        } else {
            searchQuery = new NativeSearchQueryBuilder()
                    .withPageable(new QPageRequest(pageNum - 1, pageSize))
                    .withQuery(QueryBuilders.matchAllQuery())
                    .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
                    .build();
        }
        Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class);
        model.addAttribute("blogs", blogs.getContent());
        model.addAttribute("pageHelper", new PageHelper<>(blogs, pageNum, pageSize));
        model.addAttribute("keyword", keyword);
        return "index";
    }
  •  高亮显示

spring-data-elasticsearch使用SearchResultMapper接口实现对搜索结果的再加工,搜索结果的高亮显示可以通过该接口的实现类来实现。

import com.alibaba.fastjson.JSON;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HighlightResultMapper implements SearchResultMapper {
    @Override
    public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> clazz, Pageable pageable) {
        long totalHits = searchResponse.getHits().getTotalHits();
        List<T> list = new ArrayList<>();
        SearchHits hits = searchResponse.getHits();
        if (hits.getHits().length> 0) {
            for (SearchHit searchHit : hits) {
                Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                T item = JSON.parseObject(searchHit.getSourceAsString(), clazz);
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    if (highlightFields.containsKey(field.getName())) {
                        try {
                            field.set(item, highlightFields.get(field.getName()).fragments()[0].toString());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
                list.add(item);
            }
        }
        return new AggregatedPageImpl<>(list, pageable, totalHits);
    }
}

对controller代码稍作修改

        String authorFieldName = "author";
        String textFieldName = "text";
        String preTags = "<span style=\"color:#F56C6C\">";
        String postTags = "</span>";
        HighlightBuilder.Field authorField = new HighlightBuilder.Field(authorFieldName).preTags(preTags).postTags(postTags);
        HighlightBuilder.Field textField = new HighlightBuilder.Field(textFieldName).preTags(preTags).postTags(postTags);

        SearchQuery searchQuery = null;
        if (StringUtils.isNotBlank(keyword)) {
            searchQuery = new NativeSearchQueryBuilder()
                    .withPageable(new QPageRequest(pageNum - 1, pageSize))
                    .withQuery(QueryBuilders.multiMatchQuery(keyword, "text", "author"))
                    .withHighlightFields(authorField, textField)
                    .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
                    .build();
        } else {
            searchQuery = new NativeSearchQueryBuilder()
                    .withPageable(new QPageRequest(pageNum - 1, pageSize))
                    .withQuery(QueryBuilders.matchAllQuery())
                    .withSort(SortBuilders.fieldSort("date").order(SortOrder.DESC))
                    .build();
        }
        Page<Blog> blogs = elasticsearchTemplate.queryForPage(searchQuery, Blog.class, new HighlightResultMapper());

效果

 

代码

链接:https://pan.baidu.com/s/13pAWNl_KLQg4RdAClYH9Rg 
提取码:qm0l 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值