SpringData整合EsTemplate实现聚合查询

1,447 阅读1分钟

前言:最近项目中有遇到需要从ES中获取数据,牵涉到一些聚合方面的操作,由于SpringBoot版本不同,Es的语法也有一些不同。

Kibana查询语句

GET rms_device_point/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "hostid": "10569"
          }
        },
        {
          "match_phrase": {
            "name": "MPU Board 0: CPU utilization"
          }
        },
        {
          "range": {
            "lastclock": {
              "gte": "2021-07-21 05:59:00"
            }
          }
        }
      ]
    }
  },
  "from": 0,
  "size": 1,
  "sort": [
    {
      "lastclock": {
        "order": "asc"
      }
    }
  ],
  "aggs": {
    "my": {
      "terms": {
        "field": "lastclock",
        "size": 1000
      },
      "aggs": {
        "my_top_hits": {
          "top_hits": {
            "_source": {
              "includes": [
                "lastvalue"
              ]
            }
          }
        }
      }
    }
  }
}

Spring 2.2.4 版本写法

BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
boolQueryBuilder.must(QueryBuilders.matchQuery("hostid", "10569"));
boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("name", "MPU Board 0: CPU utilization"));
boolQueryBuilder.must(QueryBuilders.rangeQuery("lastclock").gt("2021-07-20 13:59:00"));

NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder)
        .withPageable(PageRequest.of(0, 1))
        .withSort(SortBuilders.fieldSort("lastclock").order(SortOrder.ASC))
        .build();

TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("my").field("lastclock").size(1000);
String[] includes = {"lastvalue"};

TopHitsAggregationBuilder my_top_hits = AggregationBuilders.topHits("my_top_hits").fetchSource(includes, null);

query.addAggregation(termsAggregationBuilder.subAggregation(my_top_hits));

Aggregations aggregations = restTemplate.query(query, new ResultsExtractor<Aggregations>() {

    @Override
    public Aggregations extract(SearchResponse searchResponse) {
        return searchResponse.getAggregations();
    }
});
Map<String, Aggregation> stringAggregationMap = aggregations.asMap();

ParsedLongTerms terms = (ParsedLongTerms)stringAggregationMap.get("my");
List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (int i = 0; i < buckets.size(); i++) {
    System.out.println("X轴:"+ buckets.get(i).getKeyAsString());
    Aggregations aggregations1 = buckets.get(i).getAggregations();
    Map<String, Aggregation> stringAggregationMap1 = aggregations1.asMap();
    ParsedTopHits topHits = (ParsedTopHits) stringAggregationMap1.get("my_top_hits");
    SearchHit[] hits = topHits.getHits().getHits();
    System.out.println("Y轴:"+hits[0].getSourceAsMap().get("lastvalue"));
}

Spring 3.3.7 版本写法

NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
builder.withQuery(QueryBuilders.boolQuery()
        .must(QueryBuilders.matchQuery("hostid", "10569"))
        .must(QueryBuilders.matchPhraseQuery("name", "MPU Board 0: CPU utilization"))
        .must(QueryBuilders.rangeQuery("lastclock").gte("2021-07-20 13:59:00"))
)
        .withPageable(PageRequest.of(0, 1))
        .withSort(SortBuilders.fieldSort("lastclock").order(SortOrder.ASC));

TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("my").field("lastclock");

String[] includes = {"lastvalue"};

TopHitsAggregationBuilder my_top_hits = AggregationBuilders.topHits("my_top_hits").fetchSource(includes, null);

builder.addAggregation(termsAggregationBuilder.subAggregation(my_top_hits));

Query query = builder.build();
SearchHits<DevicePointHistoryES> searchHits = restTemplate.search(query, DevicePointHistoryES.class);
searchHits.forEach(e -> {
    System.out.println(e.getContent().toString());
});
Aggregations aggregations = searchHits.getAggregations();
Map<String, Aggregation> stringAggregationMap = aggregations.asMap();
ParsedLongTerms terms = (ParsedLongTerms)stringAggregationMap.get("my");

List<? extends Terms.Bucket> buckets = terms.getBuckets();
for (int i = 0; i < buckets.size(); i++) {
    System.out.println("X轴:"+ buckets.get(i).getKeyAsString());
    Aggregations aggregations1 = buckets.get(i).getAggregations();
    Map<String, Aggregation> stringAggregationMap1 = aggregations1.asMap();
    ParsedTopHits topHits = (ParsedTopHits) stringAggregationMap1.get("my_top_hits");
    SearchHit[] hits = topHits.getHits().getHits();
    System.out.println("Y轴:"+hits[0].getSourceAsMap().get("lastvalue"));
}