注意
この記事は,2018年3月6日に書いたものです.
Introduction
本記事では,全文検索エンジンである Elasticsearch を Go言語 から扱うための手法についてまとめます.Elasticsearch を Go とを連携するための手法は,検索してもあまり多くの情報が出てきません.その上,若干つまづきやすいポイントもありますので,この記事が,Elasticsearch と Go を連携しようと苦慮している人の助けになれば幸いです.
Docker による準備
主題に入る前に,そもそも,Elasticsearch と Go を連携するための手法が必要になってきます.本記事では,Docker と docker-compose を併用した連携手法を提示します.
Go のために,下記のような Dockerfile を用意しましょう.
FROM golang:1.9
ENV APPNAME TestApp
RUN mkdir -p /go/src/$APPNAME
WORKDIR /go/src/$APPNAME
ADD . /go/src/$APPNAME
RUN go get -v
これを,Elasticsearch と連携したい Go サーバのトップディレクトリに設置します.次に,下記のような docker-compose.yml
を作成します.
version: '3'
services:
app:
build: .
command: ["./wait-for-it.sh", "elastic:9200", "-t", "30", "--", "go", "run", "main.go"]
volumes:
- .:/go/src/TestApp
ports:
- "8080:8080"
depends_on:
- elasticsearch
elasticsearch:
image: elasticsearch
command: elasticsearch
ports:
- "9200:9200"
何てことのない普通の docker-compose.yml
ですが,注意する点がいくつかあります.Elasticsearch サーバが起動しきっていない状態で Go サーバが起動してはいけないので, wait-for-it.sh というシェルスクリプトを用いて,Go サーバが起動するまで 30 秒の遅延を置くことにしています. なお,参考にした Medium の記事を文献 [1] に示します.
ちなみに, wait-for-it.sh
は,下記のリンクから取得することができます.
https://github.com/vishnubob/wait-for-it/blob/master/wait-for-it.sh
これにて,Elasticsearch と Go を連携するための準備は終わりです.次節に,Elasticsearch と Go を連携するためのパッケージの紹介とその手法について述べます.
Elasticsearch と Go
Elasticsearch を Go から呼出す方法はいくつかあります.例えば,Elastic 社公式のクライアントとして go-elasticsearch がありますが,こちらは WIP です.elastic という著名なパッケージがありますので,通常はこちらを使用しましょう.以下に godoc を示します.
https://godoc.org/github.com/olivere/elastic
さてやるぞ,と思って,前節で構築した環境で, GoDoc の通り動かそうとすると失敗します.おそらく, No Elasticsearch Node Available
と表示されるはずです.
このようなエラーが発生する理由ですが,Docker コンテナから返ってくる Elasticsearch サーバの IP アドレスは Private なものであるため,外部からアクセスできないということだそうです [2][3].Sniffing をオフにすれば外部 IP からアクセスできますので,そのようにしましょう.下記の通りにすれば,正しく接続できるはずです.
client, err := elastic.NewClient(elastic.SetURL("http://elasticsearch:9200"))
if err != nil {
panic(err)
}
あとは,下記の通りにすれば Elasticsearch サーバに向けて REST リクエストなどを送ることができますし,Gin などと連携して HTTP Client を作ることもできます.
package main
import (
"github.com/olivere/elastic"
"context"
)
func main() {
client, err := elastic.NewClient(
elastic.SetURL("http://elasticsearch:9200"),
elastic.SetSniff(false),
)
if err != nil {
panic(err)
}
defer client.Stop()
resp, err := client.Get().
Index("index").
Type("Type").
Id("Id").
Do(context.Background())
if err != nil {
panic(err)
}
}
Conclusion
以上,Elasticsearch と Go を連携する上でつまづきやすいポイントのまとめでした.
Top comments (0)