elasticsearch,Go,elasticsearch" /> elasticsearch,Go,elasticsearch" />

如何在Go中访问弹性响应值

如何在Go中访问弹性响应值,go,elasticsearch,Go,elasticsearch,我正在使用go elasticsearch,这是elastic的官方软件包。这是我的弹性反应: { "took": 12, "timed_out": false, "_shards": { "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, &

我正在使用go elasticsearch,这是elastic的官方软件包。这是我的弹性反应:

{
  "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
              }
            }
          },
      ]
   }
}
我想迭代“选项”,我已经尝试过:

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)
    }
}
它在最后一个for循环的第3行抛出此错误:

不能覆盖选项(类型接口{})


我是新来的。我需要知道如何访问弹性响应字段。例如,我如何读取选项的_id字段?

您发布为JSON的Elasticsearch响应似乎不完全正确(缺少几个括号和糟糕的缩进)。不过,我已经进行了编辑,因此无需担心

关于循环问题,您的for循环应该是这样的:

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)
    }
}
您忘了提到像这样的范围
选项。([]接口{})

这给了我如下输出:

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]

我希望这就是你想要实现的目标。:)

JSON数据似乎并不完全正确。可以使用将数据转换为结构定义。然后,您可以更轻松地使用该结构。如果你不想走这条路,你可以选择一个名为
temp
(代码中没有显示)的变量,但它的类型是
interface{}
(空接口)。您需要在那里对列表类型(或映射)执行类型断言,否则它将无法编译。不过,使用structs的方式更易于阅读和编写。谢谢。我编辑了我的答案,你的答案真的很有趣。谢谢!还有一个问题:我如何访问选项字段,例如文本或_id?更一般地说,我怎样才能用它制作一个漂亮的JSON呢?这是一种映射。要访问字段,我可能建议您仔细阅读此答案-如果您仍然面临访问字段的问题,请告诉我。我会相应地更新我的答案。谢谢@Harshit。根据你的答案和链接,我找到了我想要的。
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]