如何在golang中将hit.Source反序列化为一个结构

时间:2016-11-23 16:36:41

标签: json elasticsearch go

我一直在使用此存储库:

https://github.com/olivere/elastic

下一个代码是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")
  }

这很好用,out就是这样的:

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

2 个答案:

答案 0 :(得分:1)

好吧,您将数据解组到文档结构中,如果您想将其打印为原始json,则可以简单地再次编组,因此只显示您在Document结构中指定的标记。

如果您希望输出为json数组,只需将所有文档存储到切片中,然后将整个事件编组

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

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

答案 1 :(得分: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")
  }

}