【问题标题】:Aggregation for multiple fields in elasticsearchelasticsearch中多个字段的聚合
【发布时间】:2019-07-25 10:53:46
【问题描述】:

elasticsearch 中是否有任何选项可以对多个字段使用聚合并获得总数? 我的查询是

"SELECT COUNT(*), currency,type,status,channel  FROM temp_index WHERE country='SG'  and  received_time=now/d group by  currency,type,status,channel 

尝试使用 RestHighLevelClient 在 Java 代码中实现上述内容,任何建议或帮助都会有所帮助。

目前我们正在使用 COUNT API

    List<Object> dashboardsDataTotal = new ArrayList<>();

        String[] channelList = { "test1", "test2", "test3", "test4", "test5", "test6" };
        String[] currencyList = { "SGD", "HKD", "USD", "INR", "IDR", "PHP", "CNY" };
        String[] statusList = { "COMPLETED", "FAILED", "PENDING", "FUTUREPROCESSINGDATE" };
        String[] paymentTypeList = { "type1", "type2" };
        String[] countryList = { "SG", "HK"};


        CountRequest countRequest = new CountRequest(INDEX);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        try {
            for (String country : countryAccess) { // per country
                Map<String, Object> dashboardsDataPerCountry = new HashMap<>();
                for (String channel : channelList) { // per channel
                    Map<String, Object> channelStore = new HashMap<>();
                    for (String paymentType : paymentTypeList) {
                        List<Object> paymentTypeStore = new ArrayList<>();

                        for (String currency : currencyList) {
                            Map<String, Object> currencyStore = new HashMap<>();
                            int receivedCount = 0;
                            for (String latestStatus : statusList) {

                                BoolQueryBuilder searchBoolQuery = QueryBuilders.boolQuery();
                                searchBoolQuery
                                        .must(QueryBuilders.termQuery("channel", channel.toLowerCase()));
                                searchBoolQuery
                                        .must(QueryBuilders.termQuery("currency", currency.toLowerCase()));
                                searchBoolQuery.must(QueryBuilders.matchPhraseQuery("source_country",
                                        country.toLowerCase()));

                                if ("FUTUREPROCESSINGDATE".equalsIgnoreCase(latestStatus)) {
                                    searchBoolQuery.must(
                                            QueryBuilders.rangeQuery("processing_date").gt(currentDateS).timeZone(getTimeZone(country)));
                                }
                                else {
                                    searchBoolQuery.must(QueryBuilders.termQuery("txn_latest_status",
                                            latestStatus.toLowerCase()));
                                }
                                searchBoolQuery.must(
                                        QueryBuilders.termQuery("paymentType", paymentType.toLowerCase()));


                                searchBoolQuery.must(QueryBuilders.rangeQuery("received_time").gte(currentDateS)
                                            .lte(currentDateS).timeZone(getTimeZone(country)));


                                searchSourceBuilder.query(searchBoolQuery);
                                countRequest.source(searchSourceBuilder);


                                // try {
                                CountResponse countResponse = restHighLevelClient.count(countRequest,
                                        RequestOptions.DEFAULT);
                                if (!latestStatus.equals("FUTUREPROCESSINGDATE")) {
                                    receivedCount += countResponse.getCount();
                                }

                                currencyStore.put(latestStatus, countResponse.getCount());

                            }
                            currencyStore.put("RECEIVED", receivedCount); // received = pending + completed + failed
                            currencyStore.put("currency", currency);
                            paymentTypeStore.add(currencyStore);

                        } // per currency end
                        channelStore.put(paymentType, paymentTypeStore);
                    } // paymentType end
                    dashboardsDataPerCountry.put(channel, channelStore);
                    dashboardsDataPerCountry.put("country", country);
                } // per channel end
                dashboardsDataTotal.add(dashboardsDataPerCountry);
            } // per country end
            restHighLevelClient.close();
        }

感谢是否有人可以为上述问题提供更好的解决方案。

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation


    【解决方案1】:

    利用 CompositeAggregationBuilder 得到聚合结果

    CompositeAggregationBuilder compositeAgg = new CompositeAggregationBuilder("aggregate_buckets", sources);
    searchSourceBuilder.aggregation(compositeAgg);
    
    
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    Aggregations aggregations = searchResponse.getAggregations();
    ParsedComposite parsedComposite = aggregations.get("aggregate_buckets");
    List<ParsedBucket> list = parsedComposite.getBuckets();
    Map<String,Object> data = new HashMap<>();
    for (ParsedBucket parsedBucket : list) {
                    data.clear();
            for (Map.Entry<String, Object> m : parsedBucket.getKey().entrySet()) {
                data.put(m.getKey(), m.getValue());
            }
            data.put("count", parsedBucket.getDocCount());
            System.out.println(data);
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-18
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 2018-06-01
      相关资源
      最近更新 更多