實現搜尋關鍵詞高亮的方式—elasticsearch與AC演算法
阿新 • • 發佈:2021-02-01
技術標籤: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);
}
結果:
以上就是實現搜尋關鍵詞高亮的方式了,如有什麼問題,歡迎指教