搜索结果高亮显示
先来看一个最基本的高亮案例
首先创建一个索引1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17PUT /blog_website
{
"mappings": {
"blogs": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
}
加条数据进去1
2
3
4
5PUT /blog_website/blogs/1
{
"title": "我的第一篇博客",
"content": "大家好,这是我写的第一篇博客,特别喜欢这个博客网站!!!"
}
搜索1
2
3
4
5
6
7
8
9
10
11
12
13GET /blog_website/blogs/_search
{
"query": {
"match": {
"title": "博客"
}
},
"highlight": {
"fields": {
"title": {}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30{
"took": 29,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.26742277,
"hits": [
{
"_index": "blog_website",
"_type": "blogs",
"_id": "1",
"_score": 0.26742277,
"_source": {
"title": "我的第一篇博客",
"content": "大家好,这是我写的第一篇博客,特别喜欢这个博客网站!!!"
},
"highlight": {
"title": [
"我的第一篇<em>博客</em>"
]
}
}
]
}
}
<em></em> 标签,会在网页中将内容变成红色,所以指定的field中,如果包含了那个搜索词的话,就会在那个field的文本中,对搜索词进行红色的高亮显示
多个filed高亮也是一样的1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25GET /blog_website/blogs/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"title": "博客"
}
},
{
"match": {
"content": "博客"
}
}
]
}
},
"highlight": {
"fields": {
"title": {},
"content": {}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33{
"took": 8,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.6390219,
"hits": [
{
"_index": "blog_website",
"_type": "blogs",
"_id": "1",
"_score": 0.6390219,
"_source": {
"title": "我的第一篇博客",
"content": "大家好,这是我写的第一篇博客,特别喜欢这个博客网站!!!"
},
"highlight": {
"title": [
"我的第一篇<em>博客</em>"
],
"content": [
"大家好,这是我写的第一篇<em>博客</em>,特别喜欢这个<em>博客</em>网站!!!"
]
}
}
]
}
}
highlight中的field,必须跟query中的field是一一对应的
三种highlight介绍
plain highlight
默认的高亮就是用的这种,底层是lucene highlight
posting highlight
设置索引的 index_options = offset 后,高亮就是用的posting highlight
优点:
- 性能比plain highlight要高,因为不需要重新对高亮文本进行分词
- 对磁盘的消耗更少
- 将文本分割为句子,并且对句子进行高亮,效果更好
删除之前的索引,然后重新建1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18PUT /blog_website
{
"mappings": {
"blogs": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"index_options": "offsets"
}
}
}
}
}
content设置了 “index_options”: “offsets” ,然后还是把之前那条数据添加进去,对content搜索高亮1
2
3
4
5
6
7
8
9
10
11
12
13GET /blog_website/blogs/_search
{
"query": {
"match": {
"content": "博客"
}
},
"highlight": {
"fields": {
"content": {}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30{
"took": 33,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.37159908,
"hits": [
{
"_index": "blog_website",
"_type": "blogs",
"_id": "1",
"_score": 0.37159908,
"_source": {
"title": "我的第一篇博客",
"content": "大家好,这是我写的第一篇博客,特别喜欢这个博客网站!!!"
},
"highlight": {
"content": [
"大家好,这是我写的第一篇<em>博客</em>,特别喜欢这个<em>博客</em>网站!!!"
]
}
}
]
}
}
其实效果跟plain是一样的
fast vector highlight
index-time时候term vector设置在mapping中,就会用fast vector highlight
- 在field值比较大(大于1MB)的情况下性能更高
还是将之前的删掉,重新建1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18PUT /blog_website
{
"mappings": {
"blogs": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"term_vector" : "with_positions_offsets"
}
}
}
}
}
在content里面设置了term_vector,就可以使用了
强制使用某种highlight
比如,对于开启了term_vector的filed,强制使用plain highlight1
2
3
4
5
6
7
8
9
10
11
12
13
14
15GET /blog_website/blogs/_search
{
"query": {
"match": {
"content": "博客"
}
},
"highlight": {
"fields": {
"content":{
"type":"plain"
}
}
}
}
自定义高亮html标签
默认是<em></em>,可以通过设置pre_tags和post_tags来自定义html标签
1 | GET /blog_website/blogs/_search |
高亮片段fragment的设置
fragment_size
先来添加一个比较长的数据1
2
3
4
5PUT /blog_website/blogs/2
{
"title": "我的第二篇博客",
"content": "大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!"
}
然后查询的时候设置 fragment_size1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18GET /blog_website/blogs/_search
{
"query": {
"match": {
"content": "博客"
}
},
"highlight": {
"pre_tags": ["<tag>"],
"post_tags": ["</tag>"],
"fields": {
"content":{
"type":"plain",
"fragment_size": 20
}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.56305844,
"hits": [
{
"_index": "blog_website",
"_type": "blogs",
"_id": "2",
"_score": 0.56305844,
"_source": {
"title": "我的第二篇博客",
"content": "大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!"
},
"highlight": {
"content": [
"大家好,这是我写的第二篇<tag>博客</tag>,特别喜欢",
"这个<tag>博客</tag>网站!!!大家好,这是我写",
"的第二篇<tag>博客</tag>,特别喜欢这个<tag>博客</tag>网站!!!大家好",
",这是我写的第二篇<tag>博客</tag>,特别喜欢这个<tag>博客</tag>",
"网站!!!大家好,这是我写的第二篇<tag>博客</tag>"
]
}
}
]
}
}
设置了fragment_size是20,然后在highlight中,就会把content按长度是20的切割成多个
使用场景:有时候field长度太长,但是你的页面不可能全显示出来,可能只需要显示一段内容就好,然后就可以通过设置fragment_size(默认是100)来将field的值进行分割
number_of_fragments
number_of_fragments: 用来指定显示多少个片段
比如上面,一共拆分出5个片段来,可能我们只需要三个,那就设置number_of_fragments为3,就可以了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19GET /blog_website/blogs/_search
{
"query": {
"match": {
"content": "博客"
}
},
"highlight": {
"pre_tags": ["<tag>"],
"post_tags": ["</tag>"],
"fields": {
"content":{
"type":"plain",
"fragment_size": 20,
"number_of_fragments": 3
}
}
}
}
返回值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32{
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.56305844,
"hits": [
{
"_index": "blog_website",
"_type": "blogs",
"_id": "2",
"_score": 0.56305844,
"_source": {
"title": "我的第二篇博客",
"content": "大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!大家好,这是我写的第二篇博客,特别喜欢这个博客网站!!!"
},
"highlight": {
"content": [
"大家好,这是我写的第二篇<tag>博客</tag>,特别喜欢",
"这个<tag>博客</tag>网站!!!大家好,这是我写",
"的第二篇<tag>博客</tag>,特别喜欢这个<tag>博客</tag>网站!!!大家好"
]
}
}
]
}
}
只显示了前3个片段