我正在使用 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
}
我已经使用大量类型断言让它工作,但这感觉并不理想:
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
}