前言
Elasticsearch中的默认高亮显示和solr的默认高亮都是基于lucene highlight的,之前没接触过搜索引擎的小伙伴可能不太了解什么是高亮下面看看官方文档上对于高亮的介绍。
Highlighters enable you to get highlighted snippets from one or more fields in your search results so you can show users where the query matches are. When you request highlights, the response contains an additional highlight element for each search hit that includes the highlighted fields and the highlighted fragments.
上面说了一大堆,说白了就是显眼点,突出重点!如下图标红的爱琴孩的博客。下面介绍下ES中的高亮实现,以及几个小问题。
高亮小例子
ES中检索加高亮其实很简单,这里主要的DSL上介绍如何实现,至于client api其实原理都差不多,不再赘述。要想实现高亮我们在query后面再加上一个highlight标签
{
"query": {
"bool": {
"must": [
{
"prefix": {
"mc": "情"
}
}
]
}
},
"highlight": {
"fields": {
"*": {}
}
}
}
上面的*号,你也可以用mc来和上面的查询条件对应上,这里用通配符*来匹配所有,查询结果如下
{
"_index": "my_index",
"_type": "jdbc",
"_id": "3402020319",
"_score": 1,
"_source": {
"qx": "340202",
"qxm": "镜湖区",
"type": "test",
"mc": "镜湖区枫情云海阁浴场",
"dz": "云龙阳光",
"@version": "1",
"sjjgdm": "3402"
},
"highlight": {
"mc": [
"镜湖区枫<em>情</em>云海阁浴场"
]
}
}
可以看到上面已经在情上面加上了<em>标签。而且highlight标签中的mc要和query查询条件对应上,否则高亮就显示不了,那上面这种情况只有在查询条件匹配上的时候才能高亮,如果我想所有字段都支持查询呢??我不可能把所有的字段都一个个慢慢拼凑到query中吧?这样一个索引可以硬刚,如果100索引需要所有字段都需要实现高亮显示,这种方式显然不好。
多字段高亮检索
如下所示具体DSL写法如下,实现多字段(或者说全字段)支持高亮检索
{
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "_all",
"query": "情"
}
}
]
}
},
"highlight": {
"require_field_match": false,
"fields": {
"*": {
}
}
}
}
注意上面的"required_field_match"是默认为true的,要想实现上面的全字段高亮显示,这个属性一定要设置为false。
自定义高亮样式
ES中默认高亮的样式就是在匹配上的字符上加上<em>标签,那么如果我们像实现和百度一样的红色高亮如何实现呢?
{
"query": {
"bool": {
"must": [
{
"query_string": {
"default_field": "_all",
"query": "情"
}
}
]
}
},
"highlight": {
"require_field_match": false,
"fields": {
"*": {
"pre_tags": [
"<font color='red'>"
],
"post_tags": [
"</font>"
]
}
}
}
}
查询结果如下
"highlight": {
"mc": [
"<font color='red'>情</font>之缘客栈"
]
}
可以看到<em>已经替换为<font>标签了。