ES[7.6.x]学习笔记(十二)高亮 和 搜索建议

ES当中大部分的内容都已经学习完了,今天呢算是对前面内容的查漏补缺,把ES中非常实用的功能整理一下,在以后的项目开发中,这些功能肯定是对你的项目加分的,我们来看看吧。

高亮

高亮在搜索功能中是十分重要的,我们希望搜索的内容在搜索结果中重点突出,让用户聚焦在搜索的内容上。我们看看在ES当中是怎么实现高亮的,我们还用之前的索引ik_index,前面的章节,我们搜索过香蕉好吃,但是返回的结果中并没有高亮,那么想要在搜索结果中,对香蕉好吃高亮该怎么办呢?我们看看,

POST /ik_index/_search { "query": { "bool": { "must": { "match": { "desc": "香蕉好吃" } } } }, "highlight": { "fields": { "desc": {} } } }

我们重点看一下请求体中的highlight部分,这部分就是对返回结果高亮的设置,fields字段中,指定哪些字段需要高亮,我们指定了desc字段,执行一下,看看结果吧。

{ "took": 73, "timed_out": false, "_shards": { "total": 1,"successful": 1,"skipped": 0,"failed": 0}, "hits": { "total": { "value": 5, "relation": "eq" }, "max_score": 1.3948275, "hits": [ { "_index": "ik_index", "_type": "_doc", "_id": "2", "_score": 1.3948275, "_source": { "id": 1, "title": "香蕉", "desc": "香蕉真好吃" }, "highlight": { "desc": [ "<em>香蕉</em>真<em>好吃</em>" ] } } ……

我们看到在返回的结果中,增加了highlight,highlight里有我们指定的高亮字段desc,它的值是<em>香蕉</em>真<em>好吃</em>,其中“香蕉”和“好吃”字段在<em>标签中,前端的小伙伴就可以针对这个<em>标签写样式了。我们再看看程序当中怎么设置高亮,继续使用上一节中的搜索的程序,

public void searchIndex() throws IOException { SearchRequest searchRequest = new SearchRequest("ik_index"); SearchSourceBuilder ssb = new SearchSourceBuilder(); QueryBuilder qb = new MatchQueryBuilder("desc","香蕉好吃"); ssb.query(qb); HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("desc"); ssb.highlighter(highlightBuilder); searchRequest.source(ssb); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] hits = response.getHits().getHits(); for (SearchHit hit : hits) { String record = hit.getSourceAsString(); HighlightField highlightField = hit.getHighlightFields().get("desc"); for (Text fragment : highlightField.getFragments()) { System.out.println(fragment.string()); } } }

我们重点关注一下HighlightBuilder,我们在发送请求前,创建HighlightBuilder,并指定高亮字段为desc。搜索结束后,我们取结果,从hit当中取出高亮字段desc,然后打印出fragment,运行一下,看看结果吧,

<em>香蕉</em>真<em>好吃</em> <em>香蕉</em>真<em>好吃</em> 橘子真<em>好吃</em> 桃子真<em>好吃</em> 苹果真<em>好吃</em>

完全符合预期,“香蕉好吃”被分词后,在搜索结果中都增加了<em>标签,我们可不可以自定义高亮标签呢?当然是可以的,我们稍微改一下程序就可以了,

HighlightBuilder highlightBuilder = new HighlightBuilder(); highlightBuilder.field("desc"); highlightBuilder.preTags("<b>"); highlightBuilder.postTags("</b>"); ssb.highlighter(highlightBuilder);

在HighlightBuilder中,使用preTags添加起始标签,指定为<b>,用postTags添加闭合标签,指定为</b>,再运行一下,看看结果,

<b>香蕉</b>真<b>好吃</b> <b>香蕉</b>真<b>好吃</b> 橘子真<b>好吃</b> 桃子真<b>好吃</b> 苹果真<b>好吃</b>

结果完全正确,用<b>替换了<em>,是不是很灵活。接下来我们再看看搜索建议。

搜索建议

“搜索建议”这个功能也是相当实用的,当我们在搜索框中输入某个字时,与这个字的相关搜索内容就会罗列在下面,我们选择其中一个搜索就可以了,省去了敲其他字的时间。我们看看ES中是怎么实现“搜索建议”的。

如果要在ES中使用“搜索建议”功能,是需要特殊设置的,要设置一个类型为completion的字段,由于之前的索引中已经有了数据,再添加字段是会报错的,索引我们新建一个索引,

PUT /my_suggester { "settings":{ "analysis":{ "analyzer":{ "default":{ "type":"ik_max_word" } } } }, "mappings":{ "dynamic_date_formats": [ "MM/dd/yyyy", "yyyy/MM/dd HH:mm:ss", "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss" ], "properties":{ "suggest":{ "type":"completion" } } } }

这已经成了我们新建索引的一个标配了,指定分词器为ik中文分词,动态字段的时间映射格式,以及搜索建议字段,注意suggest字段的类型为completion。我们再添加字段的时候,就要为suggest字段添加值了,如下:

POST /my_suggester/_doc { "title":"天气", "desc":"今天天气不错", "suggest": { "input": "天气" } } POST /my_suggester/_doc { "title":"天空", "desc":"蓝蓝的天空,白白的云", "suggest": { "input": "天空" } }

我们向索引中添加了两条数据,大家需要额外注意的是suggest字段的赋值方法,要使用input,我们看一下数据,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywyzd.html