go - 如何在 golang 中处理 Elasticsearch 回复的嵌套结构?
问题描述
我有一个用 Go 编写的 API 服务,使用 gin-gonic,它由 Elasticsearch 服务支持。查询命中 API,API 服务器查询 Elasticsearch,Elasticsearch 将搜索结果回复给 API,API 将结果返回给启动流程的一方。所有这些都“有效”,端到端,但有一个问题。
在 Elasticsearch 中,我有 20 个索引——每个索引都有数千个文档。当我使用 go-elasticsearch 通过 gin-gonic 查询 Elasticsearch 中的一个索引时,我得到了一个 Elasticsearch 结果,它被解组到这些结构中:
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"`
}
我的问题是,当上面显示为“customForIndex”类型的结构的 esResult.Hits.Hitlist.Source 字段根据我查询的索引而有所不同时。
我想做的是:
var esres esResult
err := json.Unmarshal(resp, &esres)
这很好用,如果我使用 customForIndex,但如果我将 Source 设置为 string 或 []byte(以便我可以单独解组 Source),它似乎不起作用。
我知道的解决方法很糟糕,是定义重复的结构(一组,每个索引),但这很糟糕,因为它会导致许多 esResult 结构、许多 Hits 结构等等,这些都是重复的。
那么如何解组 Elasticsearch 回复,以便获得回复的自定义部分?
换一种说法,如果我从 Elasticsearch 获取回复,并直接将其传递给 API 服务器(进而传递给客户端),而不进行任何处理,那么它包含各种(与客户端无关的)Elasticsearch 信息。所以我的计划是去掉所有这些,只在 Elasticsearch 回复中包含来自 Source 对象的数据。但是如果我解组 esResult,esResult 本身在其他索引上是无效的,因为子结构不同。
想法?任何帮助,将不胜感激。基本上我的问题与在 golang 中解组嵌套结构有关,并且恰好出现在 Elasticsearch 用例中,因为大多数(但不是全部)结构在索引之间是重复的。
解决方案
我正在阅读您的答案,我记得当我与弹性战斗只返回我需要的东西时。
真的我不知道您是如何进行查询的(如果您可以共享一些代码,那就太好了)
但是,就我而言, 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"]
}
}
}
}
}
}
之后,他们阅读了回复,阅读结果以:
for _, hit := range values["aggregations"].(map[string]interface{})["top_values"].(map[string]interface{})["buckets"].([]interface{})
在这个“FOR”语句中,我做了一个包含“hit”的结构的 Marshall,然后我用我的结构做了一个 unmarshal。
var totalValue MyStruct
marshalTotal, _ := json.Marshal(hit)
_ = json.Unmarshal(marshalTotal, &totalValue)
您需要在结构中使用与弹性结果相同的标签名称。
MyProperty string `json:"elasticNameField"`
另一方面,也许您可以使用 [Olivera] 1库,根据我的经验,它是一个很好的库,但我能够在查询的响应时间上发现一些差异。
我希望您可以使用此信息来解决您的问题。
问候,
推荐阅读
- nginx - 保护和授权从 nginx/nchan 到 auth 服务器的 GET 请求请求
- java - 这会打印出 SOP.Number@566776ad 无法弄清楚如何让它只打印出值
- javascript - 使用 Promise 和 async 进行 protobufjs 加载调用
- xcode - iOS:如何快速获取 cocoapods 的更新版本
- javascript - 算法 - 搜索和替换字符串
- javascript - 材质 UI 选项卡不适用于滚动到
- python - Flask SQLAlchemy 不会创建记录(DateTimeField)
- php - 如何在 php 中从 json {"x":"y"} 到 {x:y} 中删除双引号
- css - 基于数组中的键值对有条件地应用css类,VueJS
- mysql - 从部署在 Kubernetes 上的应用程序访问外部 MySQL 实例