注:version:elasticsearch-7.11.2
添加测试数据
#新建索引
PUT /high_light_test
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
#或者用这种写法新建索引,可以设置默认分词器
PUT /high_light_test
{
"settings" : {
"index" : {
"analysis.analyzer.default.type": "ik_max_word"
},
"number_of_shards": 1,
"number_of_replicas": 0
}
}
PUT /high_light_test/_doc/1
{
"title": "2021年最新好看的电影推荐",
"content": "新年又到了,2021年最新好看的电影有不少,我给大家推荐几部:balabala"
}
一.高亮显示语法
#单条件查询高亮显示
GET /high_light_test/_search
{
"query": {
"match": {
"title": "最新电影推荐"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
#组合查询高亮显示。在 highlight 里面填写要高亮显示的字段
GET /high_light_test/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "新电影"
}
},
{
"match": {
"content": "最新电影推荐"
}
}
]
}
},
"highlight": {
"fields": {
"title": {},
"content": {}
}
}
}
<em>会让搜索词红色高亮显示
设置高亮字体颜色
高亮字体默认显示红色,我们也可以改变高亮字体的颜色。例:
(fields: * 代表所有field都高亮显示)
#组合查询高亮显示
GET /high_light_test/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "最新电影推荐"
}
},
{
"match": {
"content": "最新电影推荐"
}
}
]
}
},
"highlight": {
"require_field_match": false,
"fields": {
"*": {
"pre_tags": [
"<font color='yellow'>"
],
"post_tags": [
"</font>"
]
}
}
}
}
二.ElasticSearch三种高亮的方式
第一种:plain highlight
默认的高亮方式,也是lucene自带的高亮方式
第二种:posting highlight
用法:在 mappings 里指定 index_options=offsets
优点:(1)性能比plain highlight要高,因为不需要重新对高亮文本进行分词
(2)对磁盘的消耗更少
例:
#删除旧索引
DELETE /high_light_test
#重建索引,指定content的 "index_options": "offsets"
PUT /high_light_test
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"index_options": "offsets"
}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
#重新添加一下测试数据
PUT /high_light_test/_doc/1
{
"title": "2021年最新好看的电影推荐",
"content": "新年又到了,2021年最新好看的电影有不少,我给大家推荐几部:balabala"
}
高亮查询:
测试结果看不出差别😔,应该是数据量小看不出性能差别。
第三种:fast vector highlight
用法:在 mappings 里设置 "term_vector" : "with_positions_offsets"
优点:对大field而言(大于1mb)性能更高
例:跟上面的类似
#重建索引,指定content的 "index_options": "offsets"
PUT /high_light_test
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"term_vector" : "with_positions_offsets"
}
}
},
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
三.强制使用某一种hightlight
比如对于开启了term_vector的field而言,可以强制使用plain highlight
例:
GET /high_light_test/_search
{
"query": {
"match": {
"content": "最新电影推荐"
}
},
"highlight": {
"fields": {
"content": {
"type": "plain"
}
}
}
}
总结:一般情况下用 plain highlight 就够了,
如果对高亮的性能要求很高,可以尝试启用 posting highlight 。
如果field的值特别大,超过了1M,那么可以用 fast vector highlight。
四.高亮显示的参数:fragment_size和number_of_fragments
在百度中搜索,不可能把所有匹配到的内容都返回,那样页面装不下。那就用到 fragment_size 和 number_of_fragments 参数。
例:
GET /high_light_test/_search
{
"query": {
"match": {
"content": "最新电影推荐"
}
},
"highlight": {
"fields": {
"content": {
"fragment_size": 1,
"number_of_fragments": 2
}
}
}
}
fragment_size:代表字段数据如果过长,则分段,每个片段数据长度为多少。长度不是字符数量,是ElasticSearch内部的数据长度计算方式。默认不对字段做分段。 number_of_fragments:代表搜索返回的高亮片段数量,默认情况下会将拆分后的所有片段都返回。