新 Java 客户端中的术语聚合 - 是否有获取结果的通用方法?

问题描述 投票:0回答:1

在新的 API Java 客户端中创建聚合时,我遇到了一个问题。 这就是我创建请求的方式。我的一些字段名称是字符串类型。有些可以是长的或双的等

  Map<String, Aggregation> termsAggregationMap= new HashMap<>();
  for (String fieldName : fieldNames)
        {
            Aggregation termsAggregation = new Aggregation.Builder()
                    .terms(new TermsAggregation.Builder().field(fieldName).order(
                            NamedValue.of("_key", SortOrder.Asc))
                            .build())
                    .build();

            map.put(fieldName, termsAggregation);
        }

SearchRequest searchRequest = new SearchRequest.Builder()
                    .index(indexAliasName).size(0)
                    .aggregations(termsAggregationMap)
                    .build();

当我阅读它时,我发现我必须知道聚合类型:string、long、double 等..

例如,为了读取字符串的聚合,我需要使用 sterms

Map<String, Aggregate> aggregationsMap = searchResponse.aggregations();
Aggregate aggregation = aggregationsMap.get(aggregationName);
for (var entry : termAggregation.sterms().buckets().array())
{
 //does something with it
 entry.key().stringValue();
 entry.docCount();
}

但为了获得长期价值,我需要使用lterms方法

termAggregation.lterms().buckets().array()

是否有更好的方法来完成一件通用的事情,而不是像旧客户端中那样每次都检查聚合类型?

elasticsearch elasticsearch-aggregation
1个回答
1
投票

我探讨了你的问题。我找不到更好的方法来通用化解决方案。 lterms、sterms、dateHistogram 等方法不可通用(还有 isLterms、isSterms、isDateHistogram 等方法)

所以我的解决方案是枚举

public enum AggregationKind {
    TERMS_STRING {
        @Override
        boolean identify(Aggregate aggregation) {
            return aggregation.isSterms();
        }

        @Override
        MultiBucketAggregateBase<?> getSpecificAggregation(Aggregate aggregation) {
            return aggregation.sterms();
        }
    },
    TERMS_LONG {
        @Override
        boolean identify(Aggregate aggregation) {
            return aggregation.isLterms();
        }

        @Override
        MultiBucketAggregateBase<?> getSpecificAggregation(Aggregate aggregation) {
            return aggregation.lterms();
        }
    },
    DATA_HISTOGRAM {
        @Override
        boolean identify(Aggregate aggregation) {
            return aggregation.isDateHistogram();
        }

        @Override
        MultiBucketAggregateBase<?> getSpecificAggregation(Aggregate aggregation) {
            return aggregation.dateHistogram();
        }
    };

    abstract boolean identify(Aggregate aggregation);

    abstract MultiBucketAggregateBase<?> getSpecificAggregation(
            Aggregate aggregation);

    public static List<?> getBucketList(Aggregate aggregation) {
        AggregationKind[] aggregationKinds = AggregationKind.values();

        for (AggregationKind aggregationKind : aggregationKinds) {
            if (aggregationKind.identify(aggregation)) {
                MultiBucketAggregateBase<?> specificAggregation = aggregationKind
                        .getSpecificAggregation(aggregation);
                return specificAggregation.buckets().array();
            }
        }
        
        return Collections.emptyList();
    }
}

使用

SearchResponse<Void> response = elasticsearchClient.search(searchRequest, Void.class);
List<StringTermsBucket> buckets = (List<StringTermsBucket>) AggregationKind
        .getBucketList(response.aggregations().get(aggregationName));

如您所见,此解决方案适用于所有 Elasticsearch 存储桶聚合(

MultiBucketAggregateBase
子类(直接和传递))

© www.soinside.com 2019 - 2024. All rights reserved.