高亮搜索:
许多应用都倾向于在每个搜索结果中 高亮 显示搜索的关键词,比如字体的加粗,改变字体的颜色等.以便让用户知道为何该文档符合查询条件。在 Elasticsearch 中检索出高亮片段也很容易。
为了执行突出显示,需要该字段的实际内容。如果存储了相关字段(已 在映射中store设置true),则将使用_source该字段,否则将加载实际字段并从中提取相关字段。
该_all字段无法从中提取_source,因此只有在映射为已store设置的情况下才能用于突出显示true。
在执行语句的前面,增加一个新的 highlight 参数:
GET /megacorp/employee/_search { "query" : { "match_phrase" : { "about" : "rock climbing" } }, "highlight": { "fields" : { "about" : {} } } }
当执行该查询时,返回结果与之前一样,与此同时结果中还多了一个叫做 highlight 的部分。这个部分包含了 about 属性匹配的文本片段,并以 HTML 标签 <em></em> 封装:
{ ... "hits": { "total": 1, "max_score": 0.23013961, "hits": [ { ... "_score": 0.23013961, "_source": { "first_name": "John", "last_name": "Smith", "age": 25, "about": "I love to go rock climbing", "interests": [ "sports", "music" ] }, "highlight": { "about": [ "I love to go <em>rock</em> <em>climbing</em>" ] } } ] } }
下面看一下JAVA,API的实现,对title字段返回的结果,高亮显示搜索关键字,也是非常的简单.
package com.bonc.test; import com.bonc.entity.ParamsEntity; import net.sf.json.JSONObject; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.text.Text; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.Operator; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * es的高亮显示; */ public class Test { private SearchResponse response = null; public String query(TransportClient client, ParamsEntity p) { List list = new ArrayList(); SearchRequestBuilder searchRequestBuilder = client.prepareSearch("").setTypes(""); searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH); searchRequestBuilder.setFrom(p.getPage()).setSize(p.getSize()).setExplain(true); HighlightBuilder highlightBuilder = new HighlightBuilder().field("title").requireFieldMatch(true); highlightBuilder.preTags("<span style=\"color:red\">"); highlightBuilder.postTags("</span>"); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); queryBuilder.must(QueryBuilders.queryStringQuery(p.getTitle()).field("title").defaultOperator(Operator.AND)); try { response = searchRequestBuilder.execute().get(); } catch (Exception e) { e.printStackTrace(); System.out.println("报错了---------------------" + e.getMessage()); } SearchHits hits = response.getHits(); long totalHits = response.getHits().totalHits; for (SearchHit hit : hits) { String sourceAsString = hit.getSourceAsString(); JSONObject jsonObject = JSONObject.fromObject(sourceAsString); Map<String, HighlightField> highlightFields = hit.getHighlightFields(); HighlightField title = highlightFields.get("title"); if (title != null) { Text[] fragments = title.fragments(); String str = ""; for (Text text : fragments) { str += text; } jsonObject.put("title", str); list.add(jsonObject); } } Map map = new HashMap<String, Object>(); map.put("total", totalHits); map.put("rows", list); return JSONObject.fromObject(map).toString(); } }