搜索结果处理
排序
elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。可以排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
GET /indexName/_search
{"query":{"match_all":{}},"sort":[{"FIELD":"desc" //排序字段和排序方式ASC、DESC 升序、降序}]
}
GET /indexName/_search
{"query":{"match_all":{}},"sort":[{"_geo_distance":{"FIELD":"纬度,经度","order":"asc","unit":"km" //单位}}]
}
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"score": {"order": "desc"},"price": {"order": "asc"}}]
}
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"_geo_distance": {"location": {"lat": 31,"lon": 121},"order": "asc","unit": "km"}}]
}
分页
elasticsearch默认情况下只返回top10的数据。而如果要查询更多的数据就需要修改分页参数了。
elasticsearch中通过修改from、size参数来控制要返回的分页结果
GET /hotel/_search
{"query":{"match_all":{}},"from":990, //分页开始的位置,默认为0"size":10, //期望获取的文档总数"sort":[{"price":"asc"}]
}
GET /hotel/_search
{"query": {"match_all": {}},"sort": [{"price":"asc"}],"from": 0,"size": 20
}
深度分页问题
ES是分布式的,所以会面临深度分页问题。例如price排序后,获取from=990,size=10的数据:
高亮处理
高亮:就是在搜索结果中把搜索关键字突出显示。
GET /hotel/_search
{"query":{"match":{"FIELD":"TEXT" //不能为match_all{} 因为高亮一定是对某个字段进行高亮}},"highlight":{"fields":{ //高亮的字段不止一个"FIELD":{"pre_tags":"<em>", //用于标记高亮字段的前置标签"post_tags":"</em>" //用于标记高亮字段的后置标签}}}
}
GET /hotel/_search
{"query": {"match": {"all": "如家"}},"highlight": {"fields": {"name": {"require_field_match": "false","pre_tags": "<em>","post_tags": "</em>"}}}
}
RestClient查询文档
match_all
void testMatchAll() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());//3.发送请求SearchResponse search = client.search(request, RequestOptions.DEFAULT);System.out.println(search);}
void testMatchAll() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//2.准备DSLrequest.source().query(QueryBuilders.matchAllQuery());//3.发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);//解析结果SearchHits hits = response.getHits();//查询的总条数long total = hits.getTotalHits().value;System.out.println("一共搜索到 "+total+"数据");//查询hit数组SearchHit[] hits1 = hits.getHits();//遍历hit数组for(SearchHit hit : hits1){//得到sourceString json=hit.getSourceAsString();//反序列化HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);//打印System.out.println(hotelDoc);System.out.println();}}
全文检索查询
全文检索的match和multi_match查询与match_all的API基本一致。差别是查询条件,也就是query部分。
multi_match
:对多个字段进行查询。
void testMulMatchAll() throws IOException {//创建requestSearchRequest request=new SearchRequest("hotel");//准备DSLSearchSourceBuilder query = request.source().query(QueryBuilders.matchQuery("all", "如家"));SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){String json = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);System.out.println();}}
void testMulMatchAll1() throws IOException {//创建requestSearchRequest request=new SearchRequest("hotel");//准备DSLSearchSourceBuilder query = request.source().query(QueryBuilders.multiMatchQuery("如家","brand","name","business"));SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){String json = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);System.out.println();}}
精确查询
void BooleanMatch() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//准备DSL//准备BooleanQueryBoolQueryBuilder boolQuery=QueryBuilders.boolQuery();//添加termboolQuery.must(QueryBuilders.termQuery("city","北京"));boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));request.source().query(boolQuery);//发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){String json = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);System.out.println();}}
排序和分页
void PageTest() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//准备DSL//准备queryrequest.source().query(QueryBuilders.matchAllQuery());//排序request.source().sort("price", SortOrder.ASC);//分页request.source().from(0).size(5);//发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){String json = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);System.out.println();}}
高亮
void HighLightTest() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//准备DSL//准备queryrequest.source().query(QueryBuilders.matchQuery("all","如家"));//高亮request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));//发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){String json = hit.getSourceAsString();HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);System.out.println(hotelDoc);System.out.println();}
}
但是为什么没有出现高亮呢?
void HighLightTest1() throws IOException {//1.准备RequestSearchRequest request=new SearchRequest("hotel");//准备DSL//准备queryrequest.source().query(QueryBuilders.matchQuery("all","如家"));//高亮request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));//发送请求SearchResponse response = client.search(request, RequestOptions.DEFAULT);SearchHits hits = response.getHits();TotalHits totalHits = hits.getTotalHits();System.out.println("搜索到的数据一共有:"+totalHits+"条");SearchHit[] hits1 = hits.getHits();for(SearchHit hit : hits1){//获取高亮结果Map<String, HighlightField> highlightFields = hit.getHighlightFields();//根据字段名获取高亮结果HighlightField highlightField = highlightFields.get("name");if(highlightField!=null){//获取高亮值String string = highlightField.getFragments()[0].string();System.out.println(string);}}}
加粗样式