Reputation: 897
I'm using go-elasticsearch which is the official package for elastic. This is my Elastic response:
{
"took": 12,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 0,
"relation": "eq"
},
"max_score": null,
"hits": [
]
},
"suggest": {
"compeletion-suggest": [
{
"text": "txt",
"offset": 0,
"length": 3,
"options": [
{
"text": "sometext_result1",
"_index": "myindex",
"_type": "_doc",
"_id": "id1",
"_score": 2.0,
"_source": {
"content_completion": {
"input": [
"sometext_result1"
],
"weight": 2
}
}
},
{
"text": "sometext_result2",
"_index": "myindex",
"_type": "_doc",
"_id": "id2",
"_score": 1.0,
"_source": {
"content_completion": {
"input": [
"sometext_result2"
],
"weight": 1
}
}
},
]
}
}
I want to iterate over "options" and I've already tried this:
var (
r map[string]interface{}
)
es, err := elasticsearch.NewDefaultClient()
var buf bytes.Buffer
query := map[string]interface{}{
"suggest": map[string]interface{}{
"compeletion-suggest": map[string]interface{}{
"prefix": "txt",
"completion": map[string]interface{}{
"field": "content_completion",
},
},
},
}
if err := json.NewEncoder(&buf).Encode(query); err != nil {
log.Fatalf("Error encoding query: %s", err)
}
res, err = es.Search(
es.Search.WithContext(context.Background()),
es.Search.WithIndex("myindex"),
es.Search.WithBody(&buf),
es.Search.WithTrackTotalHits(true),
es.Search.WithPretty(),
)
defer res.Body.Close()
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
}
for _, suggestion := range r["suggest"].(map[string]interface{})["compeletion-suggest"].([]interface{}) {
options := suggestion.(map[string]interface{})["options"]
for _, option := range options {
log.Printf(" * option=%s", option)
}
}
It throws this error at 3rd line of the last for loop:
cannot range over options (type interface {})
for _, suggestion := range r["suggest"].(map[string]interface{})["compeletion-suggest"].([]interface{}) {
options := suggestion.(map[string]interface{})["options"]
for _, option := range options {
log.Printf(" * option=%s", option)
}
}
I'm new to Go. I need to know how to access elastic response fields. For example, How can I read _id field of options?
Upvotes: 0
Views: 1712
Reputation: 1565
The Elasticsearch response which you've posted as JSON seems to not entirely correct (few brackets are missing and bad indentation) I've made an edit though, so no need to worry.
Coming to loop issue, this how your for-loop should like:
for _, suggestion := range r["suggest"].(map[string]interface{})["compeletion-suggest"].([]interface{}) {
options := suggestion.(map[string]interface{})["options"]
for _, option := range options.([]interface{}) {
log.Printf(" * option=%s", option)
}
}
You forget to mention range like this options.([]interface{})
This gives me output like this:
2020/06/28 23:57:03 * option=map[_id:id1 _index:myindex _score:%!s(float64=2) _source:map[content_completion:map[input:[sometext_result1] weight:%!s(float64=2)]] _type:_doc text:sometext_result1]
2020/06/28 23:57:03 * option=map[_id:id2 _index:myindex _score:%!s(float64=1) _source:map[content_completion:map[input:[sometext_result2] weight:%!s(float64=1)]] _type:_doc text:sometext_result2]
I hope this is what you're trying to achieve. :)
Upvotes: 1