es多字段聚合,聚合后分页,聚合后having等操作

ES使用场景

es聚合的应用场景是很多,不过,有时候,还会有多个字段聚合,聚合后分页,聚合后having的需求

多个字段聚合

		//构造查询对象
		SearchRequest baseSubOrderIndexRequest = CloudBaseQueryBuilder.getBaseSubOrderIndexRequest();
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = CloudBaseQueryBuilder.getBaseSubOrderDimensionBoolQuery(vo);
        // 采购方式
        if(vo.getBugTypes()!=null && vo.getBugTypes().size()>0){
            boolQuery.filter(QueryBuilders.termsQuery("buyType",vo.getBugTypes()));
        }
        if(StringUtils.isNotEmpty(vo.getSupplierName())){
            boolQuery.filter(QueryBuilders.termQuery("supplierName",vo.getSupplierName()));
        }
        if(StringUtils.isNotEmpty(vo.getUnitName())){
            boolQuery.filter(QueryBuilders.termQuery("unitName",vo.getUnitName()));
        }
        sourceBuilder.query(boolQuery);
		//最外层的聚合
		TermsAggregationBuilder percentageInfo = AggregationBuilders.terms("percentage_info").field(vo.getType().equals("1")?"unitName.keyword":"supplierName.keyword").size(Integer.MAX_VALUE).order(BucketOrder.aggregation(getTurnOverSumName(),false));
		//在第一层聚合的基础上
		percentageInfo.subAggregation(  AggregationBuilders.terms("provinceName")
                    .field("provinceName.keyword")
                    .size(1));
            percentageInfo.subAggregation(  AggregationBuilders.terms("cityName")
                    .field("cityName.keyword")
                    .size(1));
            percentageInfo.subAggregation(  AggregationBuilders.terms("areaName")
                    .field("areaName.keyword")
                    .size(1));
            percentageInfo.subAggregation(  AggregationBuilders.terms("cgUnitIndustry")
                    .field("cgUnitIndustry.keyword")
                    .size(1));

聚合后分页

Elasticsearch 聚合后是不支持分页的
性能角度——聚合分页会在大量的记录中产生性能问题。
正确性角度——聚合的文档计数不准确.
但是,公司的一些要求,要进行分页,大致有两种思路

  1. 聚合排序后的结果放到list中,利用list进行分页,这种方式,每次查询都是查询全部,并且所有的数据都放到内存中,是有性能问题的,适合数据量小的场景
  2. 利用Elasticsearch 的BucketSortPipelineAggregationBuilder类,这个类时用来构造
    bucket_sort管道聚合来实现分页
    中文释义:一个父管道聚合,对其父多桶聚合的桶进行排序。可以指定零个或多个排序字段以及相应的排序顺序。每个桶可以根据它的_key、_count或它的子集合进行排序。此外,可以设置参数from和size,以便截断结果桶。
	    // 聚合分页
        if ((!ObjectUtils.isEmpty(vo.getPageNo())) && (!ObjectUtils.isEmpty(vo.getPageSize()))) {
            percentageInfo.subAggregation(new BucketSortPipelineAggregationBuilder("bucket_field", Arrays.asList(new FieldSortBuilder(getTurnOverSumName()).order(SortOrder.DESC))).from((vo.getPageNo() - 1) * vo.getPageSize()).size(vo.getPageSize()));
        }
        //分组总条数
        List<? extends Terms.Bucket> totalBuckets = ((Terms) masterAggregations.get("percentage_info_total")).getBuckets();
        //分组总条数
        totalBuckets.size();
        percentageInfo.subAggregation(AggregationBuilders
                .sum("turnOverSum")
                .field("totalPrice"));

聚合后having

聚合之后还不能满足我们的需求,比如要过滤出价格大于某个值的数据
Elasticsearch 提供了bucketSelector的写法

	
		if(StringUtils.isNotEmpty(vo.getTotalPrice())){
            //(1) 设置脚本
            Script script = new Script("params.turnOverSum >="+vo.getTotalPrice());

            //(2) 声明BucketPath,用于后面的bucket筛选
            Map<String, String> bucketsPathsMap = new HashMap<>(2);
            bucketsPathsMap.put("turnOverSum", "turnOverSum");

            //(3) 构建bucket selector 实现having条件筛选过滤
            BucketSelectorPipelineAggregationBuilder bs =
                    PipelineAggregatorBuilders.bucketSelector("having", bucketsPathsMap,script);
            percentageInfo.subAggregation(bs);
        }

最后

		sourceBuilder.aggregation(percentageInfo);
        baseSubOrderIndexRequest.source(sourceBuilder);

        SearchResponse response = elasticsearchClient.search(baseSubOrderIndexRequest, RequestOptions.DEFAULT);
        log.debug(()->sourceBuilder.toString());
        List<DataReportDTO> list=new ArrayList<>();
        Aggregations masterAggregations = response.getAggregations();

分页参考链接
having参考链接

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Elasticsearch字段聚合是指在一个索引中,对多个字段进行聚合操作,以便更好地分析数据。这种聚合方式可以帮助用户更好地理解数据,发现数据中的规律和趋势,从而更好地做出决策。在Elasticsearch中,可以使用聚合框架来实现多字段聚合,具体操作可以参考官方文档。 ### 回答2: Elasticsearch是一个流行的开源搜索引擎,它支持许多聚合操作。在Elasticsearch中,聚合是一种方法,用于对数据进行分组和计算。常用的聚合操作包括sum、avg、max、min等,除此之外还有复杂的聚合操作,比如多字段聚合。 多字段聚合是一种聚合操作,它可以将多个字段的数据进行聚合,并生成一个聚合结果。这个结果可以是一个数值、一个文本字符串、一个日期、一个地理位置等等,具体根据数据的类型而定。为了使用多字段聚合操作,我们需要指定要聚合字段。同时,我们也需要指定如何对这些字段进行聚合(如何计算、如何分组等) 在多字段聚合中,我们可以使用Elasticsearch提供的各种Aggregation类型,包括Metrics Aggregation、Bucket Aggregation、Pipeline Aggregation和Matrix Aggregation等。每种类型都具有不同的功能和特点,可以根据实际需求自由组合使用,实现复杂的聚合操作。 以Bucket Aggregation为例,Bucket Aggregation是一种将文档分组的聚合方法。我们可以使用Bucket Aggregation来按照多个字段进行分组,生成聚合结果。具体实现时,我们可以使用Elasticsearch中的Terms 和Histogram Aggregation来分别按照字符串和数值进行分组。我们可以通过指定不同的字段聚合计算方式,来实现各种不同的多字段聚合操作。 总之,多字段聚合Elasticsearch中非常重要的聚合操作之一,它可以对多个字段的数据进行复杂的聚合计算,为搜索引擎的用户提供更加优质的搜索结果。通过学习和掌握多字段聚合的方法和技巧,我们可以更好地利用Elasticsearch的强大功能,实现高效、快速、准确的搜索。 ### 回答3: Elasticsearch是一个流行的分布式全文搜索和分析引擎,可以轻松地处理各种类型的数据,并支持多字段聚合。多字段聚合是指在多个字段上执行聚合操作以获取分析结果的过程。在Elasticsearch中,可以使用聚合桶来实现这些操作。 首先,要执行多字段聚合,必须使用"aggs"关键字,它可以包含多个聚合。例如,以下查询将同时执行两个聚合,一个是根据year和genre字段计算电影数量的聚合,另一个是根据rating和genre字段计算平均评级的聚合: ``` { "aggs": { "by_year_genre": { "terms": { "script": "doc['year'].value + '|' + doc['genre'].value" } }, "by_rating_genre": { "avg": { "field": "rating" }, "terms": { "field": "genre" } } } } ``` 在这个查询中,第一个聚合使用"terms"桶来计算每个year/genre组合的电影数量。 "script"参数连接两个字段,以便在聚合过程中进行分组。 第二个聚合使用"avg"聚合来计算每个genre组合的平均评级,并使用"terms"桶进行分组。 另一个非常有用的聚合是按日期范围进行聚合。 以下查询显示了如何按月份进行聚合: ``` { "aggs": { "by_month": { "date_histogram": { "field": "date", "interval": "month", "format": "yyyy-MM" } } } } ``` 在上面的聚合中,"date_histogram"桶将按月份对结果进行分组,并使用"yyyy-MM"格式来指定日期格式。Elasticsearch还支持许多其他类型的聚合,包括范围聚合、嵌套聚合和指标聚合。 总之,Elasticsearch是强大的搜索和分析工具,可以轻松地执行多字段聚合操作。通过使用聚合桶,可以对结果进行分组、计数、平均值等分析,并在结果中显示有关数据的有用信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值