7.3.10 高亮显示
高亮显示可以将搜索结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。
在搜索语句中添加highlight即可实现,如下:
Post: http://127.0.0.1:9200/xc_course/doc/_search
{
"_source" : [ "name", "studymodel", "description","price"],
"query": {
"bool" : {
"must":[
{
"multi_match" : {
"query" : "开发框架",
"minimum_should_match": "50%",
"fields": [ "name^10", "description" ],
"type":"best_fields"
}
}
],
"filter": [
{ "range": { "price": { "gte": 0 ,"lte" : 100}}}
]
}
},
"sort" : [
{
"price" : "asc"
}
],
"highlight": {
"pre_tags": ["<tag1>"],
"post_tags": ["</tag2>"],
"fields": {
"name": {},
"description":{}
}
}
}
运行结果:
{
"took": 182,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 3,
"max_score": null,
"hits": [
{
"_index": "xc_course",
"_type": "doc",
"_id": "1",
"_score": null,
"_source": {
"price": 38.6,
"studymodel": "201002",
"name": "Bootstrap开发",
"description": "Bootstrap是由Twitter推出的一个前台页面开发框架,是一个非常流行的开发框架,此框架集成了多种页面效果。此开发框架包含了大量的CSS、JS程序代码,可以帮助开发者(尤其是不擅长页面开发的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。"
},
"highlight": {
"name": [
"Bootstrap<tag1>开发</tag2>"
],
"description": [
"Bootstrap是由Twitter推出的一个前台页面<tag1>开发</tag2><tag1>框架</tag2>,是一个非常流行的<tag1>开发</tag2><tag1>框架</tag2>,此<tag1>框架</tag2>集成了多种页面效果。",
"此<tag1>开发</tag2><tag1>框架</tag2>包含了大量的CSS、JS程序代码,可以帮助<tag1>开发</tag2>者(尤其是不擅长页面<tag1>开发</tag2>的程序人员)轻松的实现一个不受浏览器限制的精美界面效果。"
]
},
"sort": [
38.6
]
},
{
"_index": "xc_course",
"_type": "doc",
"_id": "2",
"_score": null,
"_source": {
"price": 68.6,
"studymodel": "201001",
"name": "java编程基础",
"description": "java语言是世界第一编程语言,在软件开发领域使用人数最多。"
},
"highlight": {
"description": [
"java语言是世界第一编程语言,在软件<tag1>开发</tag2>领域使用人数最多。"
]
},
"sort": [
68.6
]
},
{
"_index": "xc_course",
"_type": "doc",
"_id": "3",
"_score": null,
"_source": {
"price": 88.6,
"studymodel": "201001",
"name": "spring开发基础",
"description": "spring 在java领域非常流行,java程序员都在用。"
},
"highlight": {
"name": [
"spring<tag1>开发</tag2>基础"
]
},
"sort": [
88.6
]
}
]
}
}
client代码如下:
//Highlight
@Test
public void testHighlight() throws IOException, ParseException {
//搜索请求对象
SearchRequest searchRequest = new SearchRequest("xc_course");
//指定类型
searchRequest.types("doc");
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//boolQuery搜索方式
//先定义一个MultiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("开发框架", "name", "description")
.minimumShouldMatch("50%")
.field("name", 10);
//定义一个boolQuery
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(multiMatchQueryBuilder);
//定义过虑器
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
searchSourceBuilder.query(boolQueryBuilder);
//设置源字段过虑,第一个参数结果集包括哪些字段,第二个参数表示结果集不包括哪些字段
searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","timestamp"},new String[]{});
//设置高亮
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<tag>");
highlightBuilder.postTags("</tag>");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
// highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
searchSourceBuilder.highlighter(highlightBuilder);
//向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//执行搜索,向ES发起http请求
SearchResponse searchResponse = client.search(searchRequest);
//搜索结果
SearchHits hits = searchResponse.getHits();
//匹配到的总记录数
long totalHits = hits.getTotalHits();
//得到匹配度高的文档
SearchHit[] searchHits = hits.getHits();
//日期格式化对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(SearchHit hit:searchHits){
//文档的主键
String id = hit.getId();
//源文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
//源文档的name字段内容
String name = (String) sourceAsMap.get("name");
//取出高亮字段
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if(highlightFields!=null){
//取出name高亮字段
HighlightField nameHighlightField = highlightFields.get("name");
if(nameHighlightField!=null){
Text[] fragments = nameHighlightField.getFragments();
StringBuffer stringBuffer = new StringBuffer();
for(Text text:fragments){
stringBuffer.append(text);
}
name = stringBuffer.toString();
}
}
//由于前边设置了源文档字段过虑,这时description是取不到的
String description = (String) sourceAsMap.get("description");
//学习模式
String studymodel = (String) sourceAsMap.get("studymodel");
//价格
Double price = (Double) sourceAsMap.get("price");
//日期
Date timestamp = dateFormat.parse((String) sourceAsMap.get("timestamp"));
System.out.println(name);
System.out.println(studymodel);
System.out.println(description);
}
}