弹性搜索中多个字段的聚合
Aggregation for multiple fields in elasticsearch
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();
}
如果有人能针对上述问题提供更好的解决方案,我们将不胜感激。
使用 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);
}
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();
}
如果有人能针对上述问题提供更好的解决方案,我们将不胜感激。
使用 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);
}