ElasticSearch 7.3 实战:聚合实战之使用Java api实现电视案例

在Elasticsearch 7.3 中,使用Java API实现聚合查询是非常常见的实践。这里给出一个虚构的电视案例,假设我们有一个电视节目索引,其中包含诸如channel(频道)、genre(类型)、aired_date(播出日期)和viewership(观众人数)等字段。现在我们想通过Java API做如下聚合分析:

  1. 按照频道名称分组,统计每个频道的节目数量。
  2. 在每个频道内,按照节目类型进一步细分,并统计每种类型的节目数量。
  3. 对每个频道的所有节目,计算平均观众人数。

以下是使用RestHighLevelClient实现这个案例的Java代码片段:

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregation.AggregationBuilders;
import org.elasticsearch.search.aggregation.bucket.terms.Terms;
import org.elasticsearch.search.aggregation.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregation.metrics.Avg;

import java.io.IOException;

public class TvShowAggregationExample {

    private RestHighLevelClient client;

    public void aggregateTvShows() throws IOException {
        // 创建搜索请求
        SearchRequest searchRequest = new SearchRequest("tv_shows");

        // 设置搜索源,此处假设我们没有特定的查询条件,只需对所有文档进行聚合
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery()); // 或者使用具体的查询条件

        // 第一层聚合:按频道分组
        TermsAggregationBuilder channelsAgg = AggregationBuilders.terms("by_channel").field("channel");
        
        // 第二层聚合:在每个频道内按类型分组
        TermsAggregationBuilder genresAgg = AggregationBuilders.terms("by_genre").field("genre");
        genresAgg.subAggregation(AggregationBuilders.avg("avg_viewership").field("viewership")); // 计算平均观众人数
        channelsAgg.subAggregation(genresAgg);

        sourceBuilder.aggregation(channelsAgg);

        searchRequest.source(sourceBuilder);

        // 执行搜索请求
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        // 解析聚合结果
        Terms byChannel = searchResponse.getAggregations().get("by_channel");
        for (Bucket channelBucket : byChannel.getBuckets()) {
            String channelName = channelBucket.getKeyAsString();
            System.out.println("Channel: " + channelName);
            Terms byGenre = channelBucket.getAggregations().get("by_genre");
            for (Bucket genreBucket : byGenre.getBuckets()) {
                String genre = genreBucket.getKeyAsString();
                long genreCount = genreBucket.getDocCount();
                Avg avgViewership = genreBucket.getAggregations().get("avg_viewership");
                double avgViewers = avgViewership.getValue();
                System.out.println("\tGenre: " + genre + ", Count: " + genreCount + ", Average Viewership: " + avgViewers);
            }
        }
    }

    // 初始化并关闭Elasticsearch客户端的部分省略...
}

在上述代码中,我们首先创建了一个搜索请求,然后在SearchSourceBuilder中设置了聚合条件。首先是顶层的按频道名称的terms聚合,接着在其内部定义了次级按节目类型的terms聚合,并在此聚合内又添加了一个计算平均观众人数的avg聚合。最后,执行搜索并解析聚合结果,输出每个频道及其包含的节目类型以及相应的观众人数统计数据。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值