es8聚合查询实例代码

一、首先在pom中先引入es8的java依赖

        <dependency>
            <groupId>co.elastic.clients</groupId>
            <artifactId>elasticsearch-java</artifactId>
            <version>8.14.2</version>
        </dependency>

版本可根据需要连接的es自己调整

二、配置文件添加

spring
  elasticsearch:
    rest:
      uris: http://连接地址:9200

这部分是我当时连接es7时使用的一直没有修改,但是也可以正常使用,如果有问题欢迎大佬指正

三、创建es连接工具类

public static ElasticsearchClient initClient(){
        String hostname = "链接地址";//链接地址
        int port = 9200;
        String username = "test";//用户名
        String password = "rMv5T*rxDsdW7zy06*==";//密码
        // 基本的用户名密码认证
        BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
        basicCredentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
        RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostname, port, "http"));
        restClientBuilder.setHttpClientConfigCallback(httpAsyncClientBuilder ->
                httpAsyncClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider));
        RestClient restClient = restClientBuilder.build();
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        ElasticsearchClient esClient = new ElasticsearchClient(transport);
        return esClient;
    }

四、聚合查询

java api代码

    @GetMapping("/testJkEs")
    @ApiOperation(value = "es聚合查询")
    @ResponseBody
    public void searchResponse() throws IOException {
        ElasticsearchClient esClient = initClient();
        Query query = RangeQuery.of(m -> m
                .field("age")
                .lte(JsonData.fromJson(String.valueOf(46)))
        )._toQuery();

        SearchResponse<EsUser> response = esClient.search(b -> b
                        .index("employee")
                        .size(0)
                        .query(query)
                        .aggregations("ages", a -> a
                                .terms(h -> h
                                        .field("name")
                                        .size(20)
                                        .order(new NamedValue<>("_count", co.elastic.clients.elasticsearch._types.SortOrder.Asc))
                                ).aggregations("sous",t -> t.max(h -> h
                                        .field("age")))
                        ),
                EsUser.class
        );
        // 处理响应
        if (response != null && response.aggregations() != null) {
            StringTermsAggregate ages = response.aggregations().get("ages").sterms();
            List<StringTermsBucket> array = ages.buckets().array();
            for (StringTermsBucket back:array){
                System.out.println(back.docCount()+"--"+back.key().stringValue());
                MaxAggregate sous = back.aggregations().get("sous").max();
                System.out.println(sous.value());
            }
        }
    }

对应的kibana中的查询语句

GET /employee/_search
{
  "query": {
    "range": {
      "age": {
        "lte": 46 
      }
    }
  }, 
  "size": 0,  
  "aggs": { 
    "ages": { 
      "terms": { 
        "field": "name", 
        "order": {
          "_count": "asc" 
        },
        "size": 20 
      },
      "aggs": { 
        "score_stats": { 
          "max": { 
            "field": "age"
          }
        }
      }
    }
  }
}

JavaApi代码因为我这是测试代码所以直接在controller里边写了,实际项目可以自己常见接口及实现层的代码,下边对代码进行解析(自己也可以把代码粘贴进大数据模型中让AI解析,内容都是差不多的)

kibana代码中的aggs是aggregations的缩写写哪一个都可以

1、请求数据

Query query = RangeQuery.of(m -> m
        .field("age")
        .lte(JsonData.fromJson(String.valueOf(46)))
)._toQuery();

这里创建了一个范围查询 (RangeQuery),它会查找 age 字段值小于或等于 46 的文档。JsonData.fromJson(String.valueOf(46)) 将整数值转换为 Elasticsearch 能够识别的 JSON 数据类型,直接写46的话类型会不对。

SearchResponse<EsUser> response = esClient.search(b -> b
                    .index("employee")
                    .size(0)
                    .query(query)
                    .aggregations("ages", a -> a
                            .terms(h -> h
                                    .field("name")
                                    .size(20)
                                    .order(new NamedValue<>("_count", co.elastic.clients.elasticsearch._types.SortOrder.Asc))
                            ).aggregations("sous",t -> t.max(h -> h
                                    .field("age")))
                    ),
            EsUser.class
        );

.index指定了要搜索的索引名称是 "employee"

.size表示不返回实际的文档,而只是获取聚合结果。

.query应用了之前创建的范围查询条件到搜索请求中。

.aggregations定义了一个名为 "ages" 的术语聚合 (terms aggregation),它会基于 name 字段的值来分组数据,并且每个桶(bucket)最多包含 20 个不同的键值。术语聚合内部又嵌套了一个名为 "sous" 的最大值聚合 (max aggregation),它计算每个 name 分组内 age 字段的最大值。

.order表示查询结果降序排列,正序的话可以不写也可以将asc改为desc

EsUser.class返回的数据对象,如果不返回就是用Void.class

2、返回结果解析

response.aggregations().get("ages").sterms();

获取聚合名称为ages的聚合结果

List<StringTermsBucket> array = ages.buckets().array();

获取桶内容列表(分组信息)

 System.out.println(back.docCount()+"--"+back.key().stringValue());

获取每个桶(分组)中的文档统计数据和分组键内容信息, back.key()后边跟的xxxValue()可以根据自己的实际情况选择使用string或其他数据类型

MaxAggregate sous = back.aggregations().get("sous").max();

 获取嵌套循环中自定义为“sous”的聚合查询,后边的max可以根据自己的情况调整为avg、min或其他内容

以上就实现了一个es8-JavaApi的聚合查询代码,有没有其他更好的实现方法本人不知道,也希望大佬来指教。以上代码是参考官网代码,具体路径如下Aggregations | Elasticsearch Java API Client [8.14] | Elastic

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值