[AWS]Amazon Elasticsearch Serviceでよく使うコマンド集(Amazon ES/Elasticsearch)

# Amazon Elasticsearch Serviceとは？
Elasticsearchとは、分散処理マルチテナント対応検索エンジンです。(全文検索)
データを蓄積するだけではなく、そのデータに属性や情報を持たせ、
高度で柔軟性の高い検索や分析が行えます。
　＃Elasticsearchが溜め込んでいる情報を、KibanaなどのBIツールで表示させます。

もともとは自サーバやAWS EC2など、サーバを立てる必要がありましたが、
そこを上手いこと、まるっと良しなにAWSが行ってくれるわけです。

基本的にはAWSコンソールをポチポチしていけば、簡単に構築することが出来ます。
　＃しかもKibanaも併せて立ててくれるんですね

# でもでも、こんなことも思うわけです
Amazon Elasticsearch Serviceは使いやすい
だがしかし！かゆいところに手が届かない（プラグイン入らないし
一体なんのmanagedなのか。。。

言いたいことを言えばボロボロ出てきますが。

まぁ、それでも使っちゃうんですけどね。

# ElasticsearchAPIをcurlで叩いてみよう
私自身、Amazon ESで作業を行う際は、AWSコンソールからはモニタリングを使うくらいで、
あとは全てcurlでデータの取得/登録/更新/削除を行っていました。
実践レベルで使用する頻度が高いAPIがあったので、まとめたいと思います。

以下、凡例となります。
ドメイン名やindex名などは環境ごと読み替えてください。

```
{ドメイン}: https://から始まるドメイン名、AWSコンソール上のドメイン.エンドポイント
例:`https://search-xxx.amazonaws.com`
```
```
{index}: ドメイン.インデックス名(.kibanaなどもインデックスにあたる)
例:twitter  .kibana  など
```

## :bangbang:注意点:bangbang:
`Ver5.x`までは、ヘッダーの`Content-Type`を`application/json`として自動認識していたが、
`Ver6.x`からは書かなければなりません(CRUDのうち、CUD)
もしヘッダーをつけなければこのようなエラーが帰ってきます

```
{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}
```

私自身、Amazon ESのドメインのバージョンを`Ver5.x`も`Ver6.x`も両方使うため、
下記のコマンド集は一律`-H "Content-Type: application/json"`を外しています。

## クラスタ/その他
### クラスタのヘルスチェック
```
$ curl -XPUT '{ドメイン}/_cluster/health?pretty'
```

### Shardの状態を確認
```
$ curl -XGET '{ドメイン}/_cat/shards?pretty'
```

### field-dataを確認
field-dataとは・・・
各fieldのデータをメモリ上に載せ、検索を高速化している。
この時、field-dataはcacheを伴い、cacheが溜まり過ぎるとOutOfMemoryErrorが発生することがある。
利用するメモリのサイズ調整ができるが、体感だHEAP_Sizeの70〜75%で運用していた。

```
$ curl -XGET '{ドメイン}/_stats/fielddata?pretty'
```

### field-dataの解放
```
$ curl -XPOST '{ドメイン}/_cache/clear' -d '
{
  "fielddata": "true"
}'
```

## 手動スナップショット取得/復元(リストア)
### 手動スナップショット取得
```
$ curl -XPUT '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}'
```

### 手動スナップショット一覧取得
```
$ curl -XGET '{ドメイン}/{S3のスナップショット保存ディレクトリ}/_all?pretty'
```

### 復元(全てを復元)
```
$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore'
```

### 特定のindexのみ復元
```
$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore' -d '
{
  "indices": "{index}"
}'
```
```
$ curl -XPOST '{ドメイン}/{S3のスナップショット保存ディレクトリ}/{任意のスナップショット名}/_restore' -d '
{
  "indices": [ "{index}", "{index}", "{index}" ]
}'
```

## 検索(search)
### range検索
```
$ curl -XGET '{ドメイン}/{index}/_search' -d '
{
  "query": {
    "range": {
      "timestamp": {
        "lte": "2017-06-30"
      }
    }
  }
}'
```

### term検索
```
$ curl -XGET '{ドメイン}/{index}/_search' -d '
{
  "query": {
    "term": {
      "_type": "xxxx"
    }
  }
}'
```

## index関連
### index作成
下記例だと、index作成時にプライマリシャードとレプリカシャードの数を指定

```
$ curl -XPUT '{ドメイン}/{index}' -d '
{
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0
    }
  }
}'
```

### 特定のindexを削除
```
$ curl -XDELETE '{ドメイン}/{index}'
```

### indexのsettingsを変更する
下記の例だと、対象indexのread-onlyを外す

```
$ curl -XPUT '{ドメイン}/{index}/_settings' -d '
{
  "index.blocks.write": true
}'
```

### indexごとの設定取得
```
$ curl -XGET '{ドメイン}/{index}/_settings'
```

### index内のドキュメントカウントを取得
```
$ curl -XGET '{ドメイン}/{index}/_count'
```

### 既存のindexから別のindexに値をコピー
もともとあるindexから別indexに生まれ変わらせる作業が発生することがある
そのとき非常に役に立つ
　＃ドキュメントの取得が遅いなど、1つのindexが肥大化してshardが足りていないケースなど
　　その場合、indexを分けてあげることで、shard数を増やしたりする
　＃query部分も`_search`と同様に書けるため便利

下記の例だと、
元ソースのindexの`2017-06-01 00:00:00`から`2017-06-01 23:59:59`のドキュメントを
ドキュメントをコピーしたいindexに`コピー`する
何度も書いてますが、あくまで`コピー`です


```
$ curl -XPOST '{ドメイン}/_reindex' -d '
{
  "source": {
    "index": {元ソースのindex},
    "query": {
      "range": {
        "timestamp": {
           "gte": "2017-06-01" 
           "lte": "2017-06-30"
        }
      }
    }
  },
  "dest": {
    "index": {ドキュメントを`コピー`したいindex}
  }
}'
```

# 感想
使い方次第で顔面蒼白です
気を付けてください