Elasticsearch入門

schedule 2021/02/02  refresh 2023/11/08

 

 

オープンソースのデータベースソフトウェアElasticsearchをご存知でしょうか?

 

JSON形式のデータをRestfulAPIでリクエストすることで操作ができるため、プログラム言語を選ばずに簡単に操作できたり、データ形式がJSONのため柔軟なデータ設計が可能だったり、オープンソースにもかかわらずデータ分析や機械学習などがデフォルト機能でそのままできてしまったりで近年急速に広がりを見せております。

 

そこでElasticsearchを使い始めた人が使う機会が多いと思われるリクエストをまとめてみました。

 

 

ノードの情報の確認

そのノードのメモリ使用量やインデックスなどの情報を確認したいときは以下のリクエストで確認しましょう。

# curl -XGET http://localhost:9200/_node/status?pretty=true


ノードのクラスタ状態の確認

そのノードのクラスタ状態を確認したいときには以下のリクエストで確認しましょう。”status”がgreenであれば正常です。

 

# curl -XGET http://localhost:9200/_cluster/health?pretty=true



 

シャード割当がされない理由の確認

2のクラスタの状態で"unassigned_shards"があると該当データにアクセスできなくなります。ノードの再起動直後はシャードが全て未割当になりますが時間の経過とともに減っていきます。もし時間が経っても0にならない場合は以下のリクエストで理由を確認して是正しましょう。

 

# curl -XGET http://localhost:9200/_cluster/allocation/explain?pretty=true

 

+ ノード間でバージョンが違う場合、primaryが一番古い場合などは問題ありませんがprimaryのノードより古いバージョンのノードがあるとクラスタできませんのでここに表示されたりします。

 

又は該当ノードのインデックスの一覧で確認したい人は以下のコマンドで確認しましょう。

 

# curl -XGET http://localhost:9200/_cat/shards?h=index,shard,prirep,state,unassigned.reason

 

 

シャードの再割当

3の”explanation”でshard has exceeded the maximum number …と一時的に失敗した旨のメッセージが出たらその中に書いてある以下のコマンドで再割り当てしましょう。

 

# curl -XPOST http://localhost:9200/_cluster/reroute?retry_failed=true&pretty=true

 

 

インデックスの一覧

インデックスの一覧を取得するときは以下のリクエストで確認しましょう。

 

# curl -XGET http://localhost:9200/_cat/indices?v

 

 

 

ただ上のリクエストだとインデックス名以外にも情報を収集する必要があるため負荷も多くレスポンスが遅くなります。なのでインデックス名だけがほしいのであれば以下のエイリアス一覧のリクエストがおすすめです。インデックスとエイリアスのマッピング情報だけですのですごく軽いです。

 

# curl -XGET http://localhost:9200/_aliases?pretty=true

 

 

インデックスのマッピング情報の確認

インデックスのマッピング情報を確認します。Elasticsearchのデータが柔軟とはいえ同一インデックスで同じパラメータに異なるデータ形式を指定できません。インデックスへのドキュメント追加に失敗したときなど確認してみましょう。

 

# curl -XGET http://localhost:9200/{index名}/_mapping?pretty=true

 

 

テンプレートの登録

テンプレートを登録しないと、全てのパラメータでデータ形式が自動判定になりインデックスによって検索のフィルタがきいたりきかなかったり、統計データにはいったりはいらなかったりしてしまうので必要に応じてmappingsを設定しましょう。

 

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/_template/{template名}
    -d ‘{
        “order”: 1,
        “version”: 1,
        “index_patterns”: [“test_*”],
        “settings”: {“index”:{“number_of shards”: 1}},
        “mappings”: {
            “properties”: {
                “value”: {“type”: “keyword”, “ignore_above”: 256},
                “object”: {
                    “type”: “nested”,
                    “properties”: {
                        “value1”: {“type”: “keyword”, “igonore_above”: 256},
                        “value2”: {“type”: “text”}
                    }
                }
            }
        }
    }’

 

 

データの検索

以下はmessage.log_yyyy.MM.DDのインデックス名でログファイルを格納しているときの検索リクエスト例です。

 

valueが “test”のもの(valueのtypeまたはsubtypeが”keyword”である必要があります)

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?pretty=true -d ‘{“query”: { “term”: {“value”: “test”}}}’

 

valueが”test”で前方一致のもの

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?pretty=true -d ‘{“query”: { “wildcard”: {“value”: “test*”}}}’

 

valueが”test”で前方一致かつvalue2が1(value2のtypeはint)のもの

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?pretty=true
    -d ‘{
        “query”: {
            “bool”: {
                “filter”: [
                    { “wildcard”: {“value”: “test*”}},
                    {“term”: {“value2”: 1}}
                ]
            }
        }
    }’

 

valueが”test”で前方一致かつvalue2が1かつ@timestampが2020/6/1から2020/11/30までのもの

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?pretty=true
    -d ‘{
        “query”: {
            “bool”: {
                “filter”: [
                    { “wildcard”: {“value”: “test*”}},
                    {“term”: {“value2”: 1}},
                    {“range”: {“@timestamp”: { “gte”: “2020-06-01T00:00:00Z”, “lt”: “2020-12-01T00:00:00Z”} } }
                ]
            }
        }
    }’
 

 

取得するパラメータをvalue3,value4だけにする

# curl -XGET -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?_source=value3,value4&pretty=true

 

 

100件取得

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?pretty=true -d ‘{“size”: 100}’

 

 

Scrollを使って2万件を5000レコード毎に受け取る

1万件を超えるデータを一度に受け取ることができないのでscrollという機能を指定して分割して受け取ります。

 

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/message.log_*/_search?scroll=1m&pretty=true -d ‘{“size”: 5000, “terminate_after”: 20000}’

 

続きを受け取るにはレスポンスの中の”scroll_id”をリクエストの中にいれて以下のようなリクエストを投げます。

 

# curl -XPOST -H “Content-Type: application/json” http://localhost:9200/_search/scroll?pretty=true -d ‘{“scroll”: “1m”, “scroll_id”: <受け取ったscroll_id>}’

 

 

データ部分が空のレスポンスが返ってきたら終りですのでscrollデータを消します。

 

Scrollはリソースを使うため数を制限されているので、そのまま放置して連続で検索するとすぐに使えなくなってしまうので以下のリクエストで使わなくなったらすぐに消しましょう。

 

ちなみにクエリストリングでscroll_idを渡してもいいのですがscroll_idの長さは可変で長すぎるときにはクエリストリングだとエラーになりますので最初からbodyに入れて送りましょう。

 

# curl -XDELETE  -H “Content-Type: application/json” http://localhost:9200/_search/scroll?pretty=true -d ‘{“scroll_id”: <受け取ったscroll_id>}’