Sanx
Sanx

Reputation: 323

How to Deserialize hit.Source into a struct in golang

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

Upvotes: 0

Views: 1996

Answers (2)

Sanx
Sanx

Reputation: 323

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")
  }

}

Upvotes: 0

hbejgel
hbejgel

Reputation: 4837

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) )

Upvotes: 1

Related Questions