B i M A P

UpdateByQuery Golang Gin API|Elasticsearch Guide

elasticsearch logo


環境配置

開發環境:MacOS Big Sur 11.2.3

部署方式:Docker Engine 20.10.5

Elasticsearch 版本:7.11

Goalng 版本:1.15

Gin Framework:v1.7.2

Golang elasticsearch client:v8


安裝 ES Official Library

在 go.mod 中加入以下字段:

require github.com/elastic/go-elasticsearch/v8 master


建立 DSL Model

這邊先建立 model,或是用 map 也可以,但因為 elasticsearch 的 DSL 通常較為複雜,我這邊選擇用 model(左圖),日後也較好維護。建立後,根據需求組合最終的 DSL(右圖),等下可以帶入 Elasticsearch client。


package models

type UpdateByQueryDSL struct {
Query DSLQuery `json:"query"`
Script string `json:"script"`
}
type DSLQuery struct {
Bool DSLBool `json:"bool"`
}
type DSLBool struct {
Should []DSLShould `json:"should"`
}
type DSLShould struct {
MatchPhrase DSLMatchPhrase `json:"match_phrase"`
}
type DSLMatchPhrase struct {
EventID string `json:"eventid.keyword"`
}
{ 
"query": {
"bool": {
"should": [ {
"match_phrase": {
"eventid.keyword": "12345678"
}
},
{
"match_phrase": {
"eventid.keyword": "87654321"
}
}
]
}
},
"script": "ctx._source.NOC_Note = '很菜'"
}


建立 Elasticsearch 連線

以需要帳號密碼的情境為例

cfg := elasticsearch.Config{ 
Addresses: []string{
"http://localhost:9001",
},
Username: "admin",
Password: "admin",
}
var err error
global.Elasticsearch, err = elasticsearch.NewClient(cfg)
if err != nil {
panic(err)
}


ES Client - UpdateByQuery

1. 將上面建立好的 DSL 轉成 buffer

2. 呼叫 ES Client UpdateByQuery,帶入 Index-pattern,並將 DSL buffer 轉成 Reader 帶入

3. 將 response 做錯誤判斷,出錯就中斷

4. 成功的話,將 response decode 進 model / map 中,後續需要可使用

var buf bytes.Buffer 
if err := json.NewEncoder(&buf).Encode(updateByQueryDSL); err != nil {
log.Fatalf("Error encoding query: %s", err)
}
res, err := global.Elasticsearch.UpdateByQuery(
[]string{"gg-alarm*"},
global.Elasticsearch.UpdateByQuery.WithBody(bytes.NewReader(buf.Bytes())),
)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.IsError() {
var e map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
} else {
log.Fatalf("[%s] %s: %s",
res.Status(),
e["error"].(map[string]interface{})["type"],
e["error"].(map[string]interface{})["reason"],
)
}
}
var r map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
log.Fatalf("Error parsing the response body: %s", err)
}




有任何問題,或是想看新主題? 聯絡我們

延伸閱讀
winstonlu的大頭照
ELK 達人

我們致力於 ELK 的各種應用,協助企業建置相關服務。我們也提供基於 ELK 的各種解決方案,有任何問題,歡迎加入我們的官方 Line,或來信詢問,期待與您面對面的機會。