ElasticSearch7.0 Java High Level Client使用教程(三:聚合查询)

前两篇介绍了es的简单条件查询,本文将在条件查询的基础上添加聚合条件进行查询,聚合查询很大的不同是在查询结果的解析上。
首先看一下这条dsl查询语句:

GET test*/_search
{
  "size": 0,
  "timeout": "60s",
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "server_name.keyword": [
              "www.test.com"
            ],
            "boost": 1
          }
        },
        {
          "match_phrase": {
            "args": {
              "query": "786754748671257",
              "slop": 0,
              "zero_terms_query": "NONE",
              "boost": 1
            }
          }
        },
        {
          "range": {
            "@timestamp": {
              "from": "2020-06-04T16:00:00.000Z",
              "to": "2020-06-04T18:00:00.000Z",
              "include_lower": true,
              "include_upper": false,
              "boost": 1
            }
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "aggregations": {
    "@timestamp": {
      "date_histogram": {
        "field": "@timestamp",
        "interval": "1h",
        "offset": 0,
        "order": {
          "_key": "asc"
        },
        "keyed": false,
        "min_doc_count": 0
      },
      "aggregations": {
        "args": {
          "terms": {
            "field": "args.keyword",
            "min_doc_count": 100,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    }
  },
  "track_total_hits": "true"
}

接下来的代码绑定查询条件部分都会围绕这条语句来写
再看一下这条语句的查询结果:

{
  "took" : 42,
  "timed_out" : false,
  "_shards" : {
    "total" : 660,
    "successful" : 660,
    "skipped" : 648,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 53,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "@timestamp" : {
      "buckets" : [
        {
          "key_as_string" : "2020-06-04T16:00:00.000Z",
          "key" : 1591286400000,
          "doc_count" : 28,
          "args" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 27,
            "buckets" : [
              {
                "key" : "dt=51&expired=1591286876393&ufi=786754748671257&zyc=5&token=cloud14&sig=5DqpNn5G2L8rtytertThyvXoyqXjIl%2BSck%3D",
                "doc_count" : 1
              }
            ]
          }
        },
        {
          "key_as_string" : "2020-06-04T17:00:00.000Z",
          "key" : 1591290000000,
          "doc_count" : 25,
          "args" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 24,
            "buckets" : [
              {
                "key" : "dt=51&expired=1591290322988&ufi=786754748671257&zyc=5&token=cloud16&sig=nARSWMB5%2BuerteregKADzmCARMRk4oXoms%3D",
                "doc_count" : 1
              }
            ]
          }
        }
      ]
    }
  }
}

接下来代码里的解析查询结果部分会围绕这个来写

代码

public class ESReadTest {

	// ES的用户名,密码,地址
    private final String user = "user";
    private final String password = "password";
    private final String hostname = "127.0.0.1";
    private String indexName;
    private RestHighLevelClient client;

	// 用来将北京时间转换成UTC时间
    public String getUTCStr(String date) {
        String returnDate = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            returnDate = new DateTime(sdf.parse(date)).plusHours(-8).toString("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return returnDate;
    }

	// 初始化Client
    public void iniES(String indexName){
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials(user, password));

        RestClientBuilder builder = RestClient.builder(
                new HttpHost(hostname, 9200))
                .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                    public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);}});
        this.client = new RestHighLevelClient(builder);
        this.indexName=indexName;
    }

	//构建请求
    public SearchResponse dslBulider() throws IOException {
        SearchRequest searchRequest = new SearchRequest(this.indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // hit 返回值(bool 查询返回条数)
        searchSourceBuilder.size(0);
//        searchSourceBuilder.from(0);
        searchSourceBuilder.trackTotalHits(true);
		// 超时时间60s
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));

		// 添加查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("server_name.keyword", "www.test.com"));
        boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("args","786754748671257"));
        boolQueryBuilder.must(QueryBuilders.rangeQuery("@timestamp").gte(getUTCStr("2020-06-05 00:00:00")).lt(getUTCStr("2020-06-05 02:00:00")));

		// 添加聚合条件 按每小时 args字段聚合
        DateHistogramAggregationBuilder  dateBuilder =  AggregationBuilders.dateHistogram("@timestamp").dateHistogramInterval(new DateHistogramInterval("1h")).field("@timestamp")
                .subAggregation(
                        AggregationBuilders.terms("args").field("args.keyword")
                );

        // 绑定条件
        searchSourceBuilder.query(boolQueryBuilder);
        searchSourceBuilder.aggregation(dateBuilder);
        searchRequest.source(searchSourceBuilder);

		// 发起请求并接收响应
        SearchResponse searchResponse = this.client.search(searchRequest, RequestOptions.DEFAULT);
		// 打印dsl语句
        System.out.println("dsl is: "+searchRequest.source());
        return searchResponse;
    }

	// 解析查询结果
    public List<JSONObject> dslParse(SearchResponse searchResponse) {
        List<JSONObject> jsonList=new ArrayList<>();
		// 获取第一层timestamp并遍历
        ParsedDateHistogram timestampList = searchResponse.getAggregations().get("@timestamp");
        for (MultiBucketsAggregation.Bucket timestamp : timestampList.getBuckets()){
			// 获取第二层args并遍历
            ParsedStringTerms argsList = timestamp.getAggregations().get("args");
            for (MultiBucketsAggregation.Bucket args : argsList.getBuckets()){
				// 获取时间、args、数量,这里的时间也是UTC时间
                JSONObject jsonObject=new JSONObject();
                jsonObject.put("date",timestamp.getKey());
                jsonObject.put("args",args.getKey());
                jsonObject.put("doc_count",args.getDocCount());
                jsonList.add(jsonObject);
            }
        }
        return jsonList;
    }

    public void closeES(){
        try {
            this.client.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void run(){
        try {
            this.iniES("test*");
			// 查询并打印结果
            List<JSONObject> jsonStringList = this.dslParse(this.dslBulider());
            for (JSONObject jsonObject : jsonStringList) {
                System.out.println(JSON.toJSONString(jsonObject));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            this.closeES();
        }
    }

    public static void main(String[] args) {
        ESReadTest esReadTest=new ESReadTest();
        esReadTest.run();
    }
}


猜你喜欢

转载自blog.csdn.net/weixin_42473019/article/details/106571595
今日推荐