自学内容网 自学内容网

Java结合ElasticSearch根据查询关键字,高亮显示全文数据。

由于es高亮显示机制的问题。当全文内容过多,且搜索中标又少时,就会出现高亮结果无法覆盖全文。因此需要根据需求手动替换。
1.根据es的ik分词器获取搜索词的分词结果。
es部分:

//中文分词解析
post /_analyze
{
    "analyzer":"ik_smart",
    "text":"谷歌浏览器"
}

//结果
{
    "tokens": [
        {
            "token": "谷歌",
            "start_offset": 0,
            "end_offset": 2,
            "type": "CN_WORD",
            "position": 0
        },
        {
            "token": "浏览器",
            "start_offset": 2,
            "end_offset": 5,
            "type": "CN_WORD",
            "position": 1
        }
    ]
}

注意:ik_smart 是最粗颗粒度,不会有重复分词。ik_max_word 是最细颗粒度,会有重复分词。高亮显示只需要最粗即可。
ik_smart:
在这里插入图片描述
ik_max_word:
在这里插入图片描述

将es的语句转为Java语句:

//主要使用的包
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.client.Request;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;


    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * 获取到es的分词结果
     *
     * @param searchContent 查询关键字
     * @return 分词结果
     */
    private List<String> getAnalyze(String searchContent) {
        List<String> tokens = new ArrayList<>();
        if (StringUtils.isNotEmpty(searchContent)) {
            String endpoint = "/_analyze";
            String body = "{\n" +
                    "  \"analyzer\": \"ik_smart\",\n" +
                    "  \"text\": \"" + searchContent + "\"\n" +
                    "}";
            try {
                Request request = new Request("POST", endpoint);
                request.setJsonEntity(body);
                Response response = restHighLevelClient.getLowLevelClient().performRequest(request);
                InputStream content = response.getEntity().getContent();
                JsonNode jsonNode = objectMapper.readTree(content);
                if (jsonNode.has("tokens")) {
                    for (JsonNode token : jsonNode.get("tokens")) {
                        tokens.add(token.get("token").asText());
                    }
                }
            } catch (IOException | UnsupportedOperationException e) {
                log.error("ES查询分词异常", e);
            }
        }
        return tokens;
    }

2.根据获取到的多个分词数据。替换全文内容。

    /**
     * 根据多个需要替换的字符,高效替换全文数据
     * @param replaceStrList 替换字符
     * @param content 全文
     * @return 高亮显示的全文
     */
    private String replaceHighlight(List<String> replaceStrList, String content) {
        StringBuffer result = new StringBuffer();
        try {
            Map<String, String> replacements = new HashMap<>();
            for (String replaceStr : replaceStrList) {
                replacements.put(replaceStr, "<font class='eslight'>" + replaceStr + "</font>");
            }
            Pattern pattern = Pattern.compile(String.join("|", replacements.keySet()));
            Matcher matcher = pattern.matcher(content);

            while (matcher.find()) {
                matcher.appendReplacement(result, replacements.get(matcher.group(0)));
            }
            matcher.appendTail(result);
        } catch (Exception e) {
            log.error("替换高亮显示异常", e);
        }
        return result.toString();
    }

此时就能将全文关键词以分词的效果高亮显示了。


原文地址:https://blog.csdn.net/qq_42031653/article/details/143730277

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!