【elasticsearch】搜索结果处理

搜索结果处理

排序

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.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //2.准备DSL
        request.source().query(QueryBuilders.matchAllQuery());
        //3.发送请求
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        System.out.println(search);
    }

    void testMatchAll() throws IOException {
        //1.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //2.准备DSL
        request.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){
            //得到source
            String 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 {
        //创建request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        SearchSourceBuilder 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 {
        //创建request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        SearchSourceBuilder 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.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        //准备BooleanQuery
        BoolQueryBuilder boolQuery=QueryBuilders.boolQuery();
        //添加term
        boolQuery.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.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
       //准备query
        request.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.准备Request
    SearchRequest request=new SearchRequest("hotel");
    //准备DSL
    //准备query
    request.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.准备Request
        SearchRequest request=new SearchRequest("hotel");
        //准备DSL
        //准备query
        request.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);
            }
        }
    }

加粗样式

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值