ES返回数据时可以直接带关键词高亮,这里自己写一个, 实现多个关键词时高亮长的关键词, 而忽略包含在长的关键词内的短关键词。
但是, 不支持内容带html标签!
keywords直接调用es的接口
/_analyze
即可获得
/**
* 多关键词高亮
*
* @param {string} content 不带html标签的字符串
* @param {array} keywords 多个关键词的数组
* @returns {string}
*/
function highlightKeywords(content, keywords) {
if (keywords === null || keywords.length == 0) {
return content;
}
//每次根据token把对象数组的每一个未匹配过的项目匹配一次
let jsons = [{"key": content, "matched": false}];
for (let i in keywords) {
let keyword = keywords[i];
if (content.toLowerCase().indexOf(keyword.toLowerCase()) < 0) {
//原内容中根本不存在这个token, 直接忽略
continue;
}
var jsonsTemp = [];
for (var k in jsons) {
if (jsons[k].matched == false) {
//未匹配过的才处理
let key = jsons[k]['key'];
if (key.length > keyword.length) {
//目标字符串比关键词长, 循环处理
while (key.length > keyword.length) {
let ix = key.toLowerCase().indexOf(keyword.toLocaleString());
if (ix > -1) {
//目标字符串中存在token
let t = null;
//前面的
if (ix > 0) {
let key0 = key.substr(0, ix);
t = {"key": key0, "matched": false};
jsonsTemp.push(t);
}
//匹配的
t = {"key": key.substr(ix, keyword.length), "matched": true};
jsonsTemp.push(t);
//后面的重新截断, 进入下一轮
if (ix < key.length - 1) {
key = key.substr(ix + keyword.length, key.length - ix - 1);
}
} else {
//目标字符串中不存在token
jsonsTemp.push({"key": key, "matched": false});
//终止循环
break;
}
}
} else {
// 目标字符串比token短, 直接添加
jsonsTemp.push({"key": key, "matched": false});
}
} else {
// 已匹配的, 直接复制
jsonsTemp.push({"key": jsons[k]['key'], "matched": true});
}
}
jsons = jsonsTemp;
}
//拼接内容
let rt = '';
for (i in jsons) {
if (jsons[i]['matched']) {
rt += '<em>' + jsons[i]['key'] + '</em>';
} else {
rt += jsons[i]['key'];
}
}
return rt;
}
var keywords = ["aben", "奔驰", "gls", "gls450", "450"];
//先把关键词按长度降序排列
keywords.sort(function(a, b){
return b.length - a.length;
});
var ts = new Date().getTime();
for (let i = 0; i < 10000; i++) {
let rt = highlightKeywords('奔驰 2021 Mercedes Benz 奔驰 GLS450 全轮驱动越野车', keywords);
}
var te = new Date().getTime();
console.log('用时:' + (te - ts) + ' ms');
不过js的高亮与es的高亮, 还是有一定差别的, 比如下图:
截图中竖线左边是js的高亮,右边是es的高亮。 es中没有高亮的就是没有参与score计算的