1. 程式人生 > 其它 >實現搜尋關鍵詞高亮的方式—elasticsearch與AC演算法

實現搜尋關鍵詞高亮的方式—elasticsearch與AC演算法

技術標籤:ElasticsearchelasticsearchAC演算法關鍵詞高亮highlight

實現搜尋關鍵詞高亮,如果你用的是elasticsearch,直接可以用elasticsearch自帶的dsl語法highlight即可,如果用的是mysql,那實現的思路就是根據關鍵詞取出搜尋的內容,然後再內容中關鍵詞的前後加上html標籤即可。接下來我就具體介紹下實現步驟

1、使用Elasticsearch,實現關鍵詞高亮

使用elasticsearch,實現高亮,只需要在dls語句中加上highlight語法即可,這樣就會返回加油高亮標籤的欄位值了,它主要是依賴於Elasticsearch底層的Lucene

基本格式如下:

{

  "highlight": {
    "fields": {
      "欄位名": {
        "pre_tags": "<mark>",
        "post_tags": "</mark>"
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
"match_phrase": { "欄位名": "欄位值" } } ] } } }

比如我們我搜索欄位name,搜尋關鍵詞高亮

{

  "highlight": {
    "fields": {
      "name": {
        "pre_tags": "<font style='color:red;'>"
, "post_tags": "</font>" } } }, "query": { "bool": { "must": [ { "match_phrase": { "name":"婉" } } ] } } }

這樣得到的結果就是以“婉”搜尋出來的記錄,記錄裡name中“婉”字前後會帶有<font style=‘color:red;’>和</font>,比如搜尋出來“佟毓婉”就會是“佟毓<font style=‘color:red;’>婉</font>”,這樣帶有標籤的記錄返回給前端,前端渲染即可

2、使用mysql,使用AC實現關鍵詞高亮

(1)依賴引入hanlp,使用AC演算法

<dependency>
    <groupId>com.hankcs</groupId>
    <artifactId>hanlp</artifactId>
    <version>portable-1.7.8</version>
</dependency>

(2)構建AC自動機

public static AhoCorasickDoubleArrayTrie<String> buildAcdt(List<String> keywords){
   AhoCorasickDoubleArrayTrie<String> acdt = new AhoCorasickDoubleArrayTrie<>();
    TreeMap<String, String> map = new TreeMap<>();
    for(String keyword : keywords){
        map.put(keyword, keyword);
    }
    acdt.build(map);
    return acdt;
}

(3)關鍵詞高亮

public static String highLight(String originText, AhoCorasickDoubleArrayTrie<String> acdt){
   List<int[]> hitLocationList = new ArrayList<>();
    // ac演算法匹配關鍵詞
    acdt.parseText(originText, (begin, end, value)->{
        int[] indexPair = new int[2];
        indexPair[0] = begin;
        indexPair[1] = end-1;
        hitLocationList.add(indexPair);
    });
    // 構建bitmap
    byte[] posStatus = new byte[originText.length()];
    for(int[] item : hitLocationList){
        posStatus[item[0]] = 1;
        for(int i=item[0]; i<=item[1]; i++){
            posStatus[i] = 1;
        }
    }
    // 字串拼接
    int lastStatus = 0;
    char[] charArray = originText.toCharArray();
    StringBuilder stringBuilder = new StringBuilder();
    for(int i=0; i<posStatus.length; i++){
        if(posStatus[i] == lastStatus){
            stringBuilder.append(charArray[i]);
        }else if(0 == lastStatus){
            stringBuilder.append("<font style='color:red;'>").append(charArray[i]);
            lastStatus = 1;
        }else if(1 == lastStatus){
            stringBuilder.append("</font>").append(charArray[i]);
            lastStatus = 0;
        }
        if(i == posStatus.length-1 && 1 == lastStatus){
            stringBuilder.append("</font>");
        }
    }

    return stringBuilder.toString();
}

(4)驗證

  public static void main(String[] args) {
     String name = "佟毓婉";
     List<String> keywords = Arrays.asList("婉");
     AhoCorasickDoubleArrayTrie<String> acdt = buildAcdt(keywords);
     String result = highLight(name, acdt);
     System.out.println("原來的內容:" + name);
     System.out.println("加高亮標籤後的內容:" + result);

 }

結果:
在這裡插入圖片描述

以上就是實現搜尋關鍵詞高亮的方式了,如有什麼問題,歡迎指教