实现搜索关键词高亮的方式—elasticsearch与AC算法

实现搜索关键词高亮,如果你用的是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);

 }

结果:
在这里插入图片描述

以上就是实现搜索关键词高亮的方式了,如有什么问题,欢迎指教

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值