许多应用都倾向于在每个搜索结果中 高亮 显示搜索的关键词,比如字体的加粗,改变字体的颜色等.以便让用户知道为何该文档符合查询条件。在 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 标签 封装:
{
...
"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 rock climbing"
]
}
}
]
}
}
下面看一下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("");
highlightBuilder.postTags("");
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 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();
map.put("total", totalHits);
map.put("rows", list);
return JSONObject.fromObject(map).toString();
}
}
如果有写的不对的地方,欢迎大家指正,如果有什么疑问,可以加QQ群:340297350,谢谢