Golang elasticsearch TypedClient 聚合如何循环结果

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

我正在使用 Elastic 的官方 Elasticsearch Go Typed Client 包来查询 uniq 服务名称,为此我构建了一个聚合搜索。查询成功,响应中包含带有服务名称的Buckets。现在我想循环存储桶并读取服务名称。

使用非类型化客户端,这就像循环response.Aggregations.StermsServices.Buckets 一样简单。但是对于 Typed 客户端,我无法弄清楚如何做到这一点(我猜缺乏如何使用正确的类型和语法的知识)。

func GetServices(env string) (Services, error) {
    var result Services
    var err error

    es, err := elasticsearch.NewTypedClient(cfg)
    if err != nil {
        return Services{}, fmt.Errorf("error creating the client: %s", err)
    }

    res, err := es.Search().
        Index(env).
        Aggregations(map[string]types.Aggregations{
            "services": {
                Terms: &types.TermsAggregation{
                    Field: some.String("serviceName.keyword"),
                },
            },
        }).
        Size(0).
        Do(context.Background())

    if err != nil {
        return Services{}, fmt.Errorf("error runnning search query: %s", err)
    }

    items := &types.TermsAggregateBaseStringTermsBucket{}
    items.Buckets = res.Aggregations["services"]

    for _, bucket := range items.Buckets {
      // Do something with bucket.Key
    }

    return result, err
}
go elasticsearch
1个回答
0
投票

我已经使用大量类型断言让它工作,但这感觉并不理想:

func GetServices(env string) (Services, error) {
    var result Services
    var err error

    es, err := elasticsearch.NewTypedClient(cfg)
    if err != nil {
        return Services{}, fmt.Errorf("error creating the client: %s", err)
    }

    res, err := es.Search().
        Index(env).
        Aggregations(map[string]types.Aggregations{
            "services": {
                Terms: &types.TermsAggregation{
                    Field: some.String("serviceName.keyword"),
                },
            },
        }).
        Size(0).
        Do(context.Background())

    if err != nil {
        return Services{}, fmt.Errorf("error runnning search query: %s", err)
    }

    aggregation := res.Aggregations["services"]

    servicesAgg, ok := aggregation.(*types.StringTermsAggregate)
    if !ok {
        return nil, errors.New("incorrect aggregation type")
    }
    
    buckets, ok := servicesAgg.Bucket([]types.StringTermsBucket)
    if !ok {
        return nil, errors.New("incorrect aggregation buckets type")
    }

    for _, bucket := range buckets {
        key, ok := item.Key.(string)
        if !ok {
            continue
        }
      // Do something with key
    }

    return result, err
}
© www.soinside.com 2019 - 2024. All rights reserved.