概念
为什么要高亮效果,因为这样很醒目,比如说文章内容很多,有一万多个字,如果搜索的时候没要高亮效果,那么你是不知道这个词语在文章的哪个位置的.
在搜索中,经常需要对搜索关键字做高亮显示,高亮显示也有其常用的参数,在这个案例中做一些常用参数的介绍。
现在搜索cars索引中remark字段中包含“大众”的document。并对“XX关键字”做高亮显示,高亮效果使用html标签,并设定字体为红色。如果remark数据过长,则只显示前20个字符。
操作
添加索引库
// 添加索引库
PUT /news_website
{
"mappings": {
"properties": {
"title": { //标题字段
"type": "text", //类型
"analyzer": "ik_max_word" //使用什么分词器
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
或者使用
PUT /news_website
{
"settings" : {
"index" : {
// 设置这个索引库的默认分词器
"analysis.analyzer.default.type": "ik_max_word"
}
}
}
插入数据
PUT /news_website/_doc/1
{
"title": "这是我写的第一篇文章",
"content": "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
}
高亮查询
GET /news_website/_doc/_search
{
"query": {
"match": {
"title": "文章"
}
},
"highlight": {
"fields": {
"title": {} //这个意思是这个title字段想做高亮效果,{}里面也可以声明你用什么颜色做高亮.
}
}
}
返回结果
注意看
highlight的代码块儿,就给title的关键字两边拼上了标签,标签在html页面上会把字体变成红色高亮效果,
是默认的标签,你如果不喜欢红色, 你也可以自定义成别的标签,实现别的颜色.
{
"took" : 458,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.2876821,
"hits" : [
{
"_index" : "news_website",
"_type" : "_doc",
"_id" : "1",
"_score" : 0.2876821,
"_source" : {
"title" : "我的第一篇文章",
"content" : "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
},
"highlight" : {
"title" : [
"我的第一篇<em>文章</em>"
]
}
}
]
}
}
这里需要注意一个细节点,就是highlight中的field,必须跟query中的field一一对齐的,如果你query中没有查询content字段,而你highlight中却配置了content字段,这样content高亮查询是没有效果的.
GET /news_website/_doc/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "文章"
}
},
{
"match": {
"content": "文章"
}
}
]
}
},
"highlight": {
"fields": {
"title": {},
"content": {}
}
}
}
常用的highlight介绍
ElasticSearch提供了三种highlight,
- plain highlight
2.lucene highlight,
3.posting highlight,如果你想使用posting highlight,就需要配置:index_options=offsets
posting highlight性能比plain highlight要高,因为不需要重新对高亮文本进行分词 ,对磁盘的消耗更少
总结一下,其实可以根据你的实际情况去考虑,一般情况下,用plain highlight也就足够了,不需要做其他额外的设置
如果对高亮的性能要求很高,可以尝试启用posting highlight
如果field的值特别大,超过了1M,比如说内容字段有可能操作1M,上万的文字就可能会超过1M, 那么可以用fast vector highlight
测试posting highlight
DELETE news_website
PUT /news_website
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"index_options": "offsets" //指定posting highlight
}
}
}
}
PUT /news_website/_doc/1
{
"title": "我的第一篇文章",
"content": "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
}
GET /news_website/_doc/_search
{
"query": {
"match": {
"content": "文章"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
执行完了之后你会发现和ElasticSearch默认的highlight表面上返回的数据是没什么区别,区别在底层.
fast vector highlight
在项目中用的比较少,
index-time term vector设置在mapping中,就会用fast verctor highlight
对大field而言(field大小大于1mb),性能更好,才能显示出来优势
delete /news_website
PUT /news_website
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"term_vector" : "with_positions_offsets" //指定使用fast vector highlight
}
}
}
}
强制使用某种highlighter
强制使用某种highlighter,比如对于开启了term vector的field而言,可以强制使用plain highlight
GET /news_website/_doc/_search
{
"query": {
"match": {
"content": "文章"
}
},
"highlight": {
"fields": {
"content": {
"type": "plain"
}
}
}
}
设置高亮html标签
设置高亮html标签,默认是标签
GET /news_website/_doc/_search
{
"query": {
"match": {
"content": "文章"
}
},
"highlight": {
"pre_tags": ["<span color='red'>"],
"post_tags": ["</span>"],
"fields": {
"content": {
"type": "plain"
}
}
}
}
高亮片段fragment的设置
在你搜索的时候,正常ElasticSearch不可能把文章的全部内容都给你展示出来,假如说文章一万多个字,在你点击百度一下的时候,这一万多个字都展示出来,那么就太大了,所以ElasticSearch有一种设置就是将最优的片段找出来返回给用户.
fragment_size: 设置文字的长度,默认是100
number_of_fragments:设置高亮的fragment文本片段有多个片段,你可以指定就显示几个片段
GET /_search
{
"query": {
"match": {
"content": "文章"
}
},
"highlight": {
"fields": {
"content": {
"fragment_size": 150,
"number_of_fragments": 3
}
}
}
}