How to Deserialize hit.Source into a struct in golang

huangapple go评论83阅读模式
英文:

How to Deserialize hit.Source into a struct in golang

问题

我一直在使用这个仓库:

https://github.com/olivere/elastic

下面的代码是一个在Golang中使用Elasticsearch查询的示例:

searchResult, err := client.Search().
    Index("mx").
    Type("postal_code").
    Source(searchJson).
    Pretty(true).
    Do()
if err != nil {
    panic(err)
}

if searchResult.Hits.TotalHits > 0 {

    for _, hit := range searchResult.Hits.Hits {
        var d Document
        err := json.Unmarshal(*hit.Source, &d)
        if err != nil {
            // 反序列化失败
        }

        fmt.Printf("Document by %s: %s\n", d.Colonia, d.Ciudad)

    }

} else {
    fmt.Print("找不到文档\n")
}

这段代码运行良好,输出结果类似于:

Document by Villa de Cortes: Distrito Federal
Document by Villa de Cortes: Sinaloa
Document by Villa de Cortes: Sinaloa

但是我需要输出结果以JSON数组的形式,类似于:

[
  {

      "cp": "03530",
      "colonia": "Villa de Cortes",
      "ciudad": "Distrito Federal",
      "delegacion": "Benito Juarez",
      "location": {
        "lat": "19.3487",
        "lon": "-99.166"
      }
  },
  {

      "cp": "81270",
      "colonia": "Villa de Cortes",
      "ciudad": "Sinaloa",
      "delegacion": "Ahome",
      "location": {
        "lat": "25.1584",
        "lon": "-107.7063"
      }
  },
  {
      "cp": "80140",
      "colonia": "Villa de Cortes",
      "ciudad": "Sinaloa",
      "delegacion": "Culiacan",
      "location": {
        "lat": "25.0239",
        "lon": "-108.032"
      }
  }
]

我该如何将hit.Source反序列化为Document结构体?

type Document struct {
  Ciudad     string `json:"ciudad"`
  Colonia    string `json:"colonia"`
  Cp         string `json:"cp"`
  Delegacion string `json:"delegacion"`
  Location   struct {
    Lat string `json:"lat"`
    Lon string `json:"lon"`
  } `json:"location"`
}

这是脚本的完整源代码:

https://gist.github.com/hectorgool/67730c8a72f2d34b09e5a8888987ea0c

英文:

i have been using this repository:

https://github.com/olivere/elastic

The next code is a example of elasticsearch query in golang :

  searchResult, err := client.Search().
      Index("mx").
      Type("postal_code").
      Source(searchJson).
      Pretty(true). 
      Do()
  if err != nil {
      panic(err)
  }

  if searchResult.Hits.TotalHits > 0 {

    for _, hit := range searchResult.Hits.Hits {
      var d Document
      err := json.Unmarshal(*hit.Source, &d)
      if err != nil {
        // Deserialization failed
      }

      fmt.Printf("Document by %s: %s\n", d.Colonia, d.Ciudad)

    }

  } else {
    fmt.Print("Found no documents\n")
  }

this works fine, the out is something like this:

Document by Villa de Cortes: Distrito Federal
Document by Villa de Cortes: Sinaloa
Document by Villa de Cortes: Sinaloa

But i need the out like json array, something like this:

[
  {

      "cp": "03530",
      "colonia": "Villa de Cortes",
      "ciudad": "Distrito Federal",
      "delegacion": "Benito Juarez",
      "location": {
        "lat": "19.3487",
        "lon": "-99.166"
      }
  },
  {

      "cp": "81270",
      "colonia": "Villa de Cortes",
      "ciudad": "Sinaloa",
      "delegacion": "Ahome",
      "location": {
        "lat": "25.1584",
        "lon": "-107.7063"
      }
  },
  {
      "cp": "80140",
      "colonia": "Villa de Cortes",
      "ciudad": "Sinaloa",
      "delegacion": "Culiacan",
      "location": {
        "lat": "25.0239",
        "lon": "-108.032"
      }
  }
]

How can i to deserialize hit.Source into a Document struct?

type Document struct {
  Ciudad     string `json:"ciudad"`
  Colonia    string `json:"colonia"`
  Cp         string `json:"cp"`
  Delegacion string `json:"delegacion"`
  Location   struct {
    Lat string `json:"lat"`
    Lon string `json:"lon"`
  } `json:"location"`
}

Here is the full source code of the script:

https://gist.github.com/hectorgool/67730c8a72f2d34b09e5a8888987ea0c

答案1

得分: 1

好的,以下是翻译好的内容:

你正在将数据解组成文档结构,如果你想将其以原始 JSON 的形式打印出来,你可以简单地再次进行编组,这样只会显示你在 Document 结构中指定的标签。

如果你希望输出为一个 JSON 数组,只需将所有的 Document 存储到一个切片中,然后对整个切片进行编组。

var documents []Document
for (...) {
    (...)
    documents = append(documents, d)
}

rawJsonDocuments, err := json.Marshal(documents)
fmt.Printf("%v", string(rawJsonDocuments))
英文:

Well, you are Unmarshalling your data into the document struct, if you want to print it as raw json you can simply Marshal it again, so only the tags you specified in your Document struct are show.

If you want the output to be a json array, just store all your Documents into a slice and then Marshal the whole thing

var documents []Document
for (...) {
    (...)
    documents = append(documents, d)
}

rawJsonDocuments, err := json.Marshal(documents)
fmt.Printf("%v", string(rawJsonDocuments) )

答案2

得分: 0

我找到了下一个解决方案:

package main

import (
  "fmt"
  j "github.com/ricardolonga/jsongo"
  "gopkg.in/olivere/elastic.v3"
)

func main() {

  term := "villa de cortes"

  searchJson := j.Object().
    Put("size", 10).
    Put("query", j.Object().
      Put("match", j.Object().
        Put("_all", j.Object().
          Put("query", term).
          Put("operator", "and")))).
    Put("sort", j.Array().
      Put(j.Object().
        Put("colonia", j.Object().
          Put("order", "asc").
          Put("mode", "avg"))))

  elasticHost := "http://172.17.0.2:9200"

  client, err := elastic.NewClient(elastic.SetURL(elasticHost))
  if err != nil {
      panic(err)
  }

  searchResult, err := client.Search().
      Index("mx").
      Type("postal_code").
      Source(searchJson).
      Pretty(true). 
      Do()
  if err != nil {
      panic(err)
  }

  if searchResult.Hits.TotalHits > 0 {

    jsonArray := j.Array()
    for _, hit := range searchResult.Hits.Hits {
      jsonArray.Put(hit.Source)   
    }

    fmt.Print(jsonArray.Indent())

  } else {
    fmt.Print("Found no documents\n")
  }

}

请注意,这是一个Go语言的代码示例,用于在Elasticsearch中搜索邮政编码。它使用了github.com/ricardolonga/jsongogopkg.in/olivere/elastic.v3这两个库。

英文:

I found the next solution:

package main

import (
  "fmt"
  j "github.com/ricardolonga/jsongo"
  "gopkg.in/olivere/elastic.v3"
)

func main() {

  term := "villa de cortes"

  searchJson := j.Object().
    Put("size", 10).
    Put("query", j.Object().
      Put("match", j.Object().
        Put("_all", j.Object().
          Put("query", term).
          Put("operator", "and")))).
    Put("sort", j.Array().
      Put(j.Object().
        Put("colonia", j.Object().
          Put("order", "asc").
          Put("mode", "avg"))))

  elasticHost := "http://172.17.0.2:9200"

  client, err := elastic.NewClient(elastic.SetURL(elasticHost))
  if err != nil {
      panic(err)
  }

  searchResult, err := client.Search().
      Index("mx").
      Type("postal_code").
      Source(searchJson).
      Pretty(true). 
      Do()
  if err != nil {
      panic(err)
  }

  if searchResult.Hits.TotalHits > 0 {

    jsonArray := j.Array()
    for _, hit := range searchResult.Hits.Hits {
      jsonArray.Put(hit.Source)   
    }

    fmt.Print(jsonArray.Indent())

  } else {
    fmt.Print("Found no documents\n")
  }

}

huangapple
  • 本文由 发表于 2016年11月24日 00:36:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/40769798.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定