概念

image.png

为什么要高亮效果,因为这样很醒目,比如说文章内容很多,有一万多个字,如果搜索的时候没要高亮效果,那么你是不知道这个词语在文章的哪个位置的.

在搜索中,经常需要对搜索关键字做高亮显示,高亮显示也有其常用的参数,在这个案例中做一些常用参数的介绍。
现在搜索cars索引中remark字段中包含“大众”的document。并对“XX关键字”做高亮显示,高亮效果使用html标签,并设定字体为红色。如果remark数据过长,则只显示前20个字符。

操作

添加索引库

  1. // 添加索引库
  2. PUT /news_website
  3. {
  4. "mappings": {
  5. "properties": {
  6. "title": { //标题字段
  7. "type": "text", //类型
  8. "analyzer": "ik_max_word" //使用什么分词器
  9. },
  10. "content": {
  11. "type": "text",
  12. "analyzer": "ik_max_word"
  13. }
  14. }
  15. }
  16. }

或者使用

  1. PUT /news_website
  2. {
  3. "settings" : {
  4. "index" : {
  5. // 设置这个索引库的默认分词器
  6. "analysis.analyzer.default.type": "ik_max_word"
  7. }
  8. }
  9. }

插入数据

  1. PUT /news_website/_doc/1
  2. {
  3. "title": "这是我写的第一篇文章",
  4. "content": "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
  5. }

高亮查询

  1. GET /news_website/_doc/_search
  2. {
  3. "query": {
  4. "match": {
  5. "title": "文章"
  6. }
  7. },
  8. "highlight": {
  9. "fields": {
  10. "title": {} //这个意思是这个title字段想做高亮效果,{}里面也可以声明你用什么颜色做高亮.
  11. }
  12. }
  13. }

返回结果

注意看 highlight的代码块儿,就给title的关键字两边拼上了标签,标签在html页面上会把字体变成红色高亮效果,
是默认的标签,你如果不喜欢红色, 你也可以自定义成别的标签,实现别的颜色.

  1. {
  2. "took" : 458,
  3. "timed_out" : false,
  4. "_shards" : {
  5. "total" : 1,
  6. "successful" : 1,
  7. "skipped" : 0,
  8. "failed" : 0
  9. },
  10. "hits" : {
  11. "total" : {
  12. "value" : 1,
  13. "relation" : "eq"
  14. },
  15. "max_score" : 0.2876821,
  16. "hits" : [
  17. {
  18. "_index" : "news_website",
  19. "_type" : "_doc",
  20. "_id" : "1",
  21. "_score" : 0.2876821,
  22. "_source" : {
  23. "title" : "我的第一篇文章",
  24. "content" : "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
  25. },
  26. "highlight" : {
  27. "title" : [
  28. "我的第一篇<em>文章</em>"
  29. ]
  30. }
  31. }
  32. ]
  33. }
  34. }

这里需要注意一个细节点,就是highlight中的field,必须跟query中的field一一对齐的,如果你query中没有查询content字段,而你highlight中却配置了content字段,这样content高亮查询是没有效果的.

  1. GET /news_website/_doc/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "should": [
  6. {
  7. "match": {
  8. "title": "文章"
  9. }
  10. },
  11. {
  12. "match": {
  13. "content": "文章"
  14. }
  15. }
  16. ]
  17. }
  18. },
  19. "highlight": {
  20. "fields": {
  21. "title": {},
  22. "content": {}
  23. }
  24. }
  25. }

常用的highlight介绍

ElasticSearch提供了三种highlight,

  1. 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

  1. DELETE news_website
  2. PUT /news_website
  3. {
  4. "mappings": {
  5. "properties": {
  6. "title": {
  7. "type": "text",
  8. "analyzer": "ik_max_word"
  9. },
  10. "content": {
  11. "type": "text",
  12. "analyzer": "ik_max_word",
  13. "index_options": "offsets" //指定posting highlight
  14. }
  15. }
  16. }
  17. }
  18. PUT /news_website/_doc/1
  19. {
  20. "title": "我的第一篇文章",
  21. "content": "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
  22. }
  23. GET /news_website/_doc/_search
  24. {
  25. "query": {
  26. "match": {
  27. "content": "文章"
  28. }
  29. },
  30. "highlight": {
  31. "fields": {
  32. "content": {}
  33. }
  34. }
  35. }

执行完了之后你会发现和ElasticSearch默认的highlight表面上返回的数据是没什么区别,区别在底层.

fast vector highlight

在项目中用的比较少,
index-time term vector设置在mapping中,就会用fast verctor highlight

对大field而言(field大小大于1mb),性能更好,才能显示出来优势

  1. delete /news_website
  2. PUT /news_website
  3. {
  4. "mappings": {
  5. "properties": {
  6. "title": {
  7. "type": "text",
  8. "analyzer": "ik_max_word"
  9. },
  10. "content": {
  11. "type": "text",
  12. "analyzer": "ik_max_word",
  13. "term_vector" : "with_positions_offsets" //指定使用fast vector highlight
  14. }
  15. }
  16. }
  17. }

强制使用某种highlighter

强制使用某种highlighter,比如对于开启了term vector的field而言,可以强制使用plain highlight

  1. GET /news_website/_doc/_search
  2. {
  3. "query": {
  4. "match": {
  5. "content": "文章"
  6. }
  7. },
  8. "highlight": {
  9. "fields": {
  10. "content": {
  11. "type": "plain"
  12. }
  13. }
  14. }
  15. }

设置高亮html标签

设置高亮html标签,默认是标签

  1. GET /news_website/_doc/_search
  2. {
  3. "query": {
  4. "match": {
  5. "content": "文章"
  6. }
  7. },
  8. "highlight": {
  9. "pre_tags": ["<span color='red'>"],
  10. "post_tags": ["</span>"],
  11. "fields": {
  12. "content": {
  13. "type": "plain"
  14. }
  15. }
  16. }
  17. }

高亮片段fragment的设置


在你搜索的时候,正常ElasticSearch不可能把文章的全部内容都给你展示出来,假如说文章一万多个字,在你点击百度一下的时候,这一万多个字都展示出来,那么就太大了,所以ElasticSearch有一种设置就是将最优的片段找出来返回给用户.

image.png

fragment_size: 设置文字的长度,默认是100
number_of_fragments:设置高亮的fragment文本片段有多个片段,你可以指定就显示几个片段

  1. GET /_search
  2. {
  3. "query": {
  4. "match": {
  5. "content": "文章"
  6. }
  7. },
  8. "highlight": {
  9. "fields": {
  10. "content": {
  11. "fragment_size": 150,
  12. "number_of_fragments": 3
  13. }
  14. }
  15. }
  16. }