实现搜索关键词高亮,如果你用的是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);
}
结果:
以上就是实现搜索关键词高亮的方式了,如有什么问题,欢迎指教