Go 如何重构JSON/Elasticsearch响应

Go 如何重构JSON/Elasticsearch响应,go,Go,我用的是Olivere v7 我正在尝试将\u id&\u source(来自ElasticSearch调用,返回JSON响应)合并到重新排序的结构中,并以该格式交付结果 这就是我的实际代码: elasticsearch, err := //actual request to ES using olivere fmt.Println(elasticsearch.Hits.Hits) 它成功地打了个电话并打印了这个: { "_score": 11.019884, &q

我用的是Olivere v7

我正在尝试将
\u id
&
\u source
(来自ElasticSearch调用,返回JSON响应)合并到重新排序的结构中,并以该格式交付结果

这就是我的实际代码:

elasticsearch, err := //actual request to ES using olivere
fmt.Println(elasticsearch.Hits.Hits)
它成功地打了个电话并打印了这个:

{
  "_score": 11.019884,
  "_index": "test",
  "_type": "_doc",
  "_id": "20",
  "_seq_no": null,
  "_primary_term": null,
  "_source": {
    "name": "Michael J.",
    "age": "22"
  }
},
{
  "_score": 11.019884,
  "_index": "test",
  "_type": "_doc",
  "_id": "21",
  "_seq_no": null,
  "_primary_term": null,
  "_source": {
    "name": "Michael Jae.",
    "age": "18"
  }
},
{
  "_score": 11.019884,
  "_index": "test",
  "_type": "_doc",
  "_id": "52",
  "_seq_no": null,
  "_primary_term": null,
  "_source": {
    "name": "Michael Jay.",
    "age": "69"
  }
},
{
  "_score": 11.019884,
  "_index": "test",
  "_type": "_doc",
  "_id": "33",
  "_seq_no": null,
  "_primary_term": null,
  "_source": {
    "name": "Michael Jo.",
    "age": "25"
  }
}
相反,我只想打印
“\u id”,“name”,“age”

因此,基于上述相同查询的期望输出为:

{
    "id": "20",
    "name": "Michael J.",
    "age": "22"
},
{
    "id": "21",
    "name": "Michael Jae.",
    "age": "18"
},
{
    "id": "52",
    "name": "Michael Jay.",
    "age": "69"
},
{
    "id": "33",
    "name": "Michael Jo.",
    "age": "25"
}
我编写了以下代码:

elasticsearch, err := //actual request to ES using olivere

type StructuredResponse struct {
    ID             string  `json:"id"`
    Email          string `json:"email"`
    Name           string `json:"name"`
}

var SR []StructuredResponse
for _, hit := range elasticsearch.Hits.Hits {
    source, err := json.Marshal(hit.Source)
    if err != nil {
        panic(err)
    }


    var SR2 StructuredResponse
    err = json.Unmarshal(source, &SR2)
    if err != nil {
        panic(err)
    }

    SR = append(SR, SR2)
}

fmt.Println(SR)
但是我迷路了,我不知道下一步会是什么,也不知道接下来该怎么做

更新:

elasticsearch.Hits.Hits
指向Olivere软件包中的此结构:

// SearchHit is a single hit.
type SearchHit struct {
    Score          *float64                       `json:"_score,omitempty"`   // computed score
    Index          string                         `json:"_index,omitempty"`   // index name
    Type           string                         `json:"_type,omitempty"`    // type meta field
    Id             string                         `json:"_id,omitempty"`      // external or internal
    Uid            string                         `json:"_uid,omitempty"`     // uid meta field (see MapperService.java for all meta fields)
    Routing        string                         `json:"_routing,omitempty"` // routing meta field
    Parent         string                         `json:"_parent,omitempty"`  // parent meta field
    Version        *int64                         `json:"_version,omitempty"` // version number, when Version is set to true in SearchService
    SeqNo          *int64                         `json:"_seq_no"`
    PrimaryTerm    *int64                         `json:"_primary_term"`
    Sort           []interface{}                  `json:"sort,omitempty"`            // sort information
    Highlight      SearchHitHighlight             `json:"highlight,omitempty"`       // highlighter information
    Source         json.RawMessage                `json:"_source,omitempty"`         // stored document source
    Fields         map[string]interface{}         `json:"fields,omitempty"`          // returned (stored) fields
    Explanation    *SearchExplanation             `json:"_explanation,omitempty"`    // explains how the score was computed
    MatchedQueries []string                       `json:"matched_queries,omitempty"` // matched queries
    InnerHits      map[string]*SearchHitInnerHits `json:"inner_hits,omitempty"`      // inner hits with ES >= 1.5.0
    Nested         *NestedHit                     `json:"_nested,omitempty"`         // for nested inner hits
    Shard          string                         `json:"_shard,omitempty"`          // used e.g. in Search Explain
    Node           string                         `json:"_node,omitempty"`           // used e.g. in Search Explain

    // HighlightFields
    // SortValues
    // MatchedFilters
}

假设导出了
elasticsearch.Hits.Hits
字段,则不需要封送输出

for _, hit := range elasticsearch.Hits.Hits {

    SR = append(SR, StructuredResponse{ID: hit.ID, Email: hit.Email, Name: Hit.Name})
}

这将为您提供一个包含完整项目集(SR)的切片。如果您想这样做的话,您应该能够将该片段封送到JSON中。

我认为它应该是这样工作的:

var srs[]结构响应
对于_,hit:=范围elasticsearch.Hits.Hits{
var-sr结构响应
如果err:=json.Unmarshal(hit.Source,&sr);err!=nil{
恐慌(错误)
}
sr.ID=hit.ID
srs=附加(srs,sr)
}

该ID已在hit中可用。请参见

为什么当前的解决方案不能让您满意?您有什么输出?@aureliar当前的解决方案实际上并没有在任何地方添加ID。它打印电子邮件和姓名字段,但将ID字段保留为空。结果elasticsearch输出中的
ID
的名称不是吗?然后应该是
json:“\u id”
。但这是行不通的,因为_id比其他数据高一个级别。另外,为什么要将其编组回json?该ID是否已在
hit
上直接可用?获取SR2不是一种类型。此外,它们没有导出。很抱歉,我应该使用
StructuredResponse
而不是SR2,更新了示例。!这开始有意义了!谢谢我的第二个问题是,调用hit.email是否会导致错误?因为它嵌套在结构中。我已经更新了我的问题,在Olivere的包
hit.ID
中也包含了结构,实际上
hit.ID
hit.Email
hit.Name
不存在。你必须解组
点击.Source
才能得到它们。看我的答案,对!这很有魅力!如果这不是太多的问题,因为我还在学习-你能解释一下我做错了什么以及你做了什么吗?1)你不需要封送
hit.Source
。它已经按照类型
json.RawMessage
进行了封送处理(请参见问题中的
SearchHit
struct)。2) 源中没有id。它只包含
姓名
年龄
。id在hit中,并且已经被Oliver的包解包。我所做的是:将
hit.Source
解包到
StructuredResponse
变量(源代码中没有id),然后从
hit
中取出
id
,并将其额外写入结构变量。这有意义吗?啊,是的,这有意义!我需要阅读更多关于切片、附加和封送/解封的工作原理,以及何时使用它的内容。我错过了RawMessage部分,但是附加部分有点混乱。我真的很感激你@特什芬克斯