如何为Elasticsearch回复处理golang中的嵌套结构?
我有一个用Go编写的API服务,使用gin gonic,它由Elasticsearch服务支持。查询命中API,API服务器查询Elasticsearch,Elasticsearch将搜索结果回复给API,API将结果返回给启动流程的一方。所有这些都“有效”,端到端,但存在一个问题 在Elasticsearch中,我有20个索引——每个索引有数千个文档。当我使用go elasticsearch通过gin gonic查询elasticsearch中的一个索引时,我得到了一个elasticsearch结果,该结果被解组到以下结构中:如何为Elasticsearch回复处理golang中的嵌套结构?,go,
elasticsearch,struct,nested,go-gin,Go,
elasticsearch,Struct,Nested,Go Gin,我有一个用Go编写的API服务,使用gin gonic,它由Elasticsearch服务支持。查询命中API,API服务器查询Elasticsearch,Elasticsearch将搜索结果回复给API,API将结果返回给启动流程的一方。所有这些都“有效”,端到端,但存在一个问题 在Elasticsearch中,我有20个索引——每个索引有数千个文档。当我使用go elasticsearch通过gin gonic查询elasticsearch中的一个索引时,我得到了一个elasticsearc
type esResult struct {
Took int `json:"took"`
Timedout bool `json:"timed_out"`
Shards jsonShards `json:"_shards"`
Hits jsonHits `json:"hits"`
}
type jsonShards struct {
Total int `json:"total"`
Successful int `json:"successful"`
Skipped int `json:"skipped"`
Failed int `json:"failed"`
}
type jsonHits struct {
Total jsonTotal `json:"total"`
Maxscore float64 `json:"max_score"`
Hitlist []jsonHitlist `json:"hits"`
}
type jsonHitlist struct {
Index string `json:"_index"`
Type string `json:"_type"`
ID string `json:"_id"`
Score float64 `json:"_score"`
Source customForIndex `json:"_source"`
// Source []byte `json:"_source"`
}
我的问题是,当esResult.Hits.Hitlist.Source字段(上面显示为“customForIndex”类型的结构)根据我查询的索引而不同时
我想做的是:
var esres esResult
err := json.Unmarshal(resp, &esres)
若我使用customForIndex,那个么这很好,但若我将Source设置为string或[]byte(以便我可以单独解组Source),那个么它似乎不起作用
我知道解决方法很糟糕,就是定义重复的结构(每个索引一个集合),但这很糟糕,因为这会导致许多esResult结构、许多Hits结构等等,它们都是重复的
那么如何解组Elasticsearch回复,以便获得回复的自定义部分呢
换句话说,如果我从Elasticsearch获取回复并将其直接传递给API服务器(从而传递给客户端),而不进行任何处理,那么它将包含各种(与客户端无关的)Elasticsearch信息。所以我的计划是去掉所有这些,只在Elasticsearch回复中包含源对象的数据。但是如果我解组esResult,esResult本身在其他索引上无效,因为子结构不同
想法?任何帮助都将不胜感激。基本上,我的问题与golang中的拆封嵌套结构有关,并且恰好出现在Elasticsearch用例中,因为大多数(但不是全部)结构在索引中都是重复的。我正在阅读你的答案,我还记得当我使用elastic只返回我需要的内容时 真的,我不知道你是如何进行查询的(如果你能分享一些代码,那就好了) 但是,在我的例子中,a做了以下几点
"aggs": {
"top_values": {
"terms": {
"field": "data.field_group.keyword"
},
"aggs": {
"top_field_hits": {
"top_hits": {
"_source": {
"includes": [ "data.field1", "data.field2", "data.field3", "data.field4"]
}
}
}
}
}
}
然后ir读取响应,从以下内容开始读取结果:
for _, hit := range values["aggregations"].(map[string]interface{})["top_values"].(map[string]interface{})["buckets"].([]interface{})
在这个“FOR”语句中,我对包含“hit”的结构进行了分析,然后对我的结构进行了解组
var totalValue MyStruct
marshalTotal, _ := json.Marshal(hit)
_ = json.Unmarshal(marshalTotal, &totalValue)
您需要在结构中使用与elastic结果相同的标记名
MyProperty string `json:"elasticNameField"`
另一方面,也许您可以使用[Olivera]库,根据我的经验,它是一个很好的库,但我能够在查询中发现响应时间的一些差异
我希望你能利用这些信息来解决你的问题
您好,我正在读您的答案,我还记得当时我用橡皮筋战斗,只返回我需要的东西 真的,我不知道你是如何进行查询的(如果你能分享一些代码,那就好了) 但是,在我的例子中,a做了以下几点
"aggs": {
"top_values": {
"terms": {
"field": "data.field_group.keyword"
},
"aggs": {
"top_field_hits": {
"top_hits": {
"_source": {
"includes": [ "data.field1", "data.field2", "data.field3", "data.field4"]
}
}
}
}
}
}
然后ir读取响应,从以下内容开始读取结果:
for _, hit := range values["aggregations"].(map[string]interface{})["top_values"].(map[string]interface{})["buckets"].([]interface{})
在这个“FOR”语句中,我对包含“hit”的结构进行了分析,然后对我的结构进行了解组
var totalValue MyStruct
marshalTotal, _ := json.Marshal(hit)
_ = json.Unmarshal(marshalTotal, &totalValue)
您需要在结构中使用与elastic结果相同的标记名
MyProperty string `json:"elasticNameField"`
另一方面,也许您可以使用[Olivera]库,根据我的经验,它是一个很好的库,但我能够在查询中发现响应时间的一些差异
我希望你能利用这些信息来解决你的问题
问候,