1.高亮显示

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

// 1.准备索引数据(在有装ik分词器的情况下)

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/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "文章"
          }
        },
        {
          "match": {
            "content": "文章"
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "title": {},
      "content": {}
    }
  }
}

// 返回结果

{
  "took" : 7,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.3664899,
    "hits" : [
      {
        "_index" : "news_website",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.3664899,
        "_source" : {
          "title" : "这是我写的第一篇文章",
          "content" : "大家好,这是我写的第一篇文章,特别喜欢这个文章门户网站!!!"
        },
        "highlight" : {
          "title" : [
            "这是我写的第一篇<em>文</em><em>章</em>"
          ],
          "content" : [
            "大家好,这是我写的第一篇<em>文</em><em>章</em>,特别喜欢这个<em>文</em><em>章</em>门户网站!!!"
          ]
        }
      }
    ]
  }
}

        <em></em>表现,会变成红色,所以说你的指定的field中,如果包含了那个搜索词的话,就会在那个field的文本中,对搜索词进行红色的高亮显示。

注:highlight中的field,必须跟query中的field一一对齐的

2、常用的highlight介绍

         1)plain highlight,lucene highlight,默认

         2)posting highlight,index_options=offsets

        (1)性能比plain highlight要高,因为不需要重新对高亮文本进行分词

        (2)对磁盘的消耗更少

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"
      }
    }
  }
}

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

GET /news_website/_search
{
  "query": {
    "match": {
      "content": "文章"
    }
  },
  "highlight": {
    "fields": {
      "content": {}
    }
  }
}

        3)fast vector highlight

                index-time term vector设置在mapping中,就会用fast verctor highlight

                (1)对大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"
        }
      }
  }
}

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

GET /news_website/_search 
{
  "query": {
    "match": {
      "content": "文章"
    }
  },
  "highlight": {
    "fields": {
      "content": {
        "type": "plain"
      }
    }
  }
}

        总结一下,其实可以根据你的实际情况去考虑,一般情况下,用plain highlight也就足够了,不需要做其他额外的设置 如果对高亮的性能要求很高,可以尝试启用posting highlight 如果field的值特别大,超过了1M,那么可以用fast vector highlight。

3.自定义高亮标签

GET /news_website/_search
{
  "query": {
    "match": {
      "content": "文章"
    }
  },
  "highlight": {
    "pre_tags": [
      "<span color='red'>"
    ],
    "post_tags": [
      "</span>"
    ],
    "fields": {
      "content": {
        "type": "plain"
      }
    }
  }
}

4.高亮片段fragment的设置

GET /news_website/_search
{
  "query": {
    "match": {
      "content": "文章"
    }
  },
  "highlight": {
    "fields": {
      "content": {
        "fragment_size": 100,
        "number_of_fragments": 3
      }
    }
  }
}

        fragment_size: Field的值,比如有长度是1万,但是你不可能在页面上显示这么长,设置要显示出来的fragment文本判断的长度,默认是100。

        number_of_fragments:高亮的fragment文本片段有多个片段,可以指定就显示几个片段。