plosxh plosxh - 1 month ago 11
JSON Question

Elasticsearch return raw json with golang Beats

I'm working on a beat that interrogate our elastic search, the goal is to get elements in elastics to modify them to avoid duplication.

i've written a search and it works :

client,err :=elasticsearch.NewClient(elasticsearch.ClientSettings{URL:host,Index:indexSel,Username: username,Password: password,Timeout: 60 * time.Second,}, nil)
if err != nil {
log.Fatal(err)
}

params := map[string]string{
"q": "_id:"+maref,
}
_, resp, err := client.SearchURI(index, "", params)

if err != nil {
log.Fatal(err)
return
}else{
fmt.Println(string(resp))
}


And here is the function from the elastic api.go :

func (es *Connection) SearchURI(index string, docType string, params map[string]string) (int, *SearchResults, error) {
status, resp, err := es.apiCall("GET", index, docType, "_search", "", params, nil)
if err != nil {
return status, nil, err
}
result, err := readSearchResult(resp)
return status, result, err
}


func readSearchResult(obj []byte) (*SearchResults, error) {
var result SearchResults
if obj == nil {
return nil, nil
}

err := json.Unmarshal(obj, &result)
if err != nil {
return nil, err
}
return &result, err
}


With the following types :

type SearchResults struct {
Took int `json:"took"`
Shards json.RawMessage `json:"_shards"`
Hits Hits `json:"hits"`
Aggs map[string]json.RawMessage `json:"aggregations"`
}

type Hits struct {
Total int
Hits []json.RawMessage `json:"hits"`
}


For now the answer is a raw json:

&{11 [123 34 116 111 116 97 108 34 58 53 44 34 115 117 99 99 101 115 115 102 117 108 34 58 53 44 34 102 97 105 108 101 100 34 58 48 125] {1 [[123 34 95 105 110 100 101 120 34 58 34 99 111 112 105 108 98 101 97 116 45 50 48 49 54 46 49 48 46 50 53 34 44 34 95 116 121 112 101 34 58 34 73 110 99 105 100 101 110 116 34 44 34 95 105 100 34 58 34 65 86 102 54 55 69 103 109 74 66 45 119 85 116 103 82 99 90 113 97 34 44 34 95 115 99 111 114 101 34 58 49 46 48 44 34 95 115 111 117 114 99 101 34 58 123 34 64 116 105 109 101 115 116 97 109 112 34 58 34 50 48 49 54 45 49 48 45 50 53 84 48 56 58 49 54 58 53 55 46 53 53 57 90 34 44 34 97 103 101 110 116 95 105 100 34 58 49 53 44 34 98 101 97 116 34 58 123 34 104 111 115 116 110 97 109 101 34 58 34 53 55 99 53 99 49 57 49 101 48 100 57 34 44 34 110 97 109 101 34 58 34 53 55 99 53 99 49 57 49 101 48 100 57 34 125 44 34 100 101 115 99 114 105 112 116 105 111 110 34 58 34 101 108 97 115 116 105 99 34 44 34 102 105 110 97 108 99 108 97 115 115 34 58 34 34 44 34 105 100 34 58 34 73 45 48 48 53 56 50 54 34 44 34 111 114 103 95 105 100 34 58 49 55 44 34 111 114 103 95 110 97 109 101 34 58 34 83 104 97 109 34 44 34 112 114 105 111 114 105 116 121 34 58 52 44 34 114 101 102 101 114 101 110 99 101 34 58 34 73 45 48 48 53 56 50 54 34 44 34 115 116 97 114 116 95 100 97 116 101 34 58 34 50 48 49 54 45 49 48 45 50 53 84 49 48 58 49 54 58 53 54 46 56 56 49 55 55 52 49 43 48 50 58 48 48 34 44 34 115 116 97 116 117 115 34 58 34 97 115 115 105 103 110 101 100 34 44 34 116 116 111 34 58 48 44 34 116 116 111 95 49 48 48 95 116 114 105 103 103 101 114 101 100 34 58 48 44 34 116 116 114 34 58 48 44 34 116 116 114 95 49 48 48 95 116 114 105 103 103 101 114 101 100 34 58 48 44 34 116 121 112 101 34 58 34 73 110 99 105 100 101 110 116 34 125 125]]} map[]}


so my question is :

How can i convert the result to ascii ?
I've read it's probably due to the json.rawMessage type that don't convert json but I can't find how to convert it.

Thanks by advance,

Plosxh.

EDIT : Solution:

Thx to icZa, here's my solution I change my "fmt.Println(resp)" into :

for _,v:=range resp.Hits.Hits{
fmt.Println(string(v))
}


it works like a charm !

Answer

json.RawMessage is a byte slice:

type RawMessage []byte

You can convert a byte slice to a string with a simple type conversion:

var result SearchResults
// ...
for _, v := range result.Hits {
    fmt.Println("Total:", v.Total, "Hits:", string(v.Hits))
}

Or:

fmt.Printf("Total: %d, Hits: %s\n", v.Total, v.Hits)

See this example:

var raw json.RawMessage
raw = json.RawMessage(`something raw`)
fmt.Println(raw)
fmt.Println(string(raw))
fmt.Printf("%s\n", raw)

Output (try it on the Go Playground):

[115 111 109 101 116 104 105 110 103 32 114 97 119]
something raw
something raw