Amazon Elasticsearch Serviceで検索できる状態まで最速で立ち上げる

# はじめに
とにかく始めてみることを目的に、Elasticsearchで全文検索できる状態を作るまでの最短距離を説明します。Amazon Elasticsearch Serviceを使います。Amazon Elasticsearch Serviceについては[下のセクション](#amazon-elasticsearch-serviceとは)を参照。
大まかな手順としては、

1. AWS上でElasticsearchサービス環境の構築
2. KibanaでElasticsearchにデータの投入

となります。

# 作成する環境
* パブリックに公開されたシングルインスタンスのElastisearch環境（URLにはランダムな文字列が入ります）
* インターネットから検索可能で、管理操作は特定IPアドレスからのみに制限
* t2.smallインスタンスを使い無料枠内（他サービスを使っていなければ）
* Elasticsearchのバージョンは7.1

# 事前準備
* インデックス名を決めておく（Elasticsearchのインデックスはデータの入れ物となるもので、RDBのDB名にあたるものです。）
* ドメイン名を決めておく（Amazon Elasticsearchでのドメイン名は、Elasticsearchクラスターを識別する名前で、1つのURLを持ちます。この下にElasticsearchの複数のインデックスを持つことができます。）
* 管理アクセスをするPCのグローバルIPアドレスを確認しておく

# 手順
### AWS上でElasticsearchサービス環境の構築
（「[Amazon Elasticsearch Serviceを触ってみた](https://qiita.com/takayuki-miura0203/items/c2ad9527d818fd20ca93)」が参考になります。）
基本的に、ドメイン名を入れて、開発およびテスト環境を選び、インスタンスサイズを入れて、アクセスポリシーを設定する以外はデフォルトのままです。

1. AWS管理コンソールにログインし東京リージョン（ap-northeast-1）に切り替え
2. 「新しいドメインの作成」ボタン
3. 「デプロイタイプの選択」で「開発およびテスト」を選択（シングルAZ）
4. 「バージョン」はデフォルトのまま
5. 「次へ」ボタン
6. 「ドメインの設定」 -> 決めていたドメイン名の入力
7. 「データノード」でt2.small.elasticsearchを選択、ノードの数は1
8. 「データノードストレージ」はデフォルトの1インスタンスのまま
9. 専用マスターノードは有効化しない（チェックを入れない）
10.  スナップショットを取る時間をUTCで指定（e.g. 19:00 UTCが04:00 JST）
11.  任意のElasticsearchクラスター設定はデフォルトのまま
11.  「次へ」ボタン
12.  「ネットワーク構成」でパブリックアクセスを選択
13.  細かいアクセスコントロールはt2.smallを選ぶと選択できないためそのまま選択しない
14.  Amazon Cognito認証を有効化はチェック入れない（別記事にて認証設定）
15.  アクセスポリシーでは「JSON定義のアクセスポリシー」で[下のアクセスポリシー例](#アクセスポリシー例)を入れる
16.  暗号化はデフォルトのドメインへのトラフィックにHTTPSのまま
17.  「次へ」ボタン
18.  「確認」ボタン
19.  ドメインのステータスがアクティブになるまで待つ

### アクセスポリシー例
```json:検索はオープン、更新や管理をIPアドレス制限
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "es:ESHttpGet",
      "Resource": "arn:aws:es:ap-northeast-1:[アカウントID]:domain/[ドメイン名]/*"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "es:ESHttpHead",
        "es:ESHttpPost",
        "es:ESHttpDelete",
        "es:ESHttpPut",
        "es:ESHttpPatch",
        "es:AddTags",
        "es:Create*",
        "es:Delete*",
        "es:Describe*",
        "es:Get*",
        "es:List*",
        "es:Purchase*",
        "es:Remove*",
        "es:Update*"
      ],
      "Resource": "arn:aws:es:ap-northeast-1: [アカウントID]:domain/[ドメイン名]/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "[アクセス元IPアドレス]/32"
        }
      }
    }
  ]
}
```

### KibanaでElasticsearchにデータの投入

1. AWS管理コンソールのElasticsearchの画面から作成したドメイン名をクリックして開く
2. Kibanaの箇所に記載されたURLでKibanaを開く（通常URLは、https://search-[ドメイン名]-[ランダムな文字列].ap-northeast-1.es.amazonaws.com/_plugin/kibana/ ）
3. KibanaのWelcome画面で「Explore on my own」をクリック
4. 左側のスパナアイコン🔧（=Dev Tools）をクリック
5. Get to Workボタンを押す
6. 左側に```GET _search```と入力し、再生ボタン▶︎を押すか、CTRL/Command+Retrunで実行して右側に結果が出るか確認する
7. [下のデータ投入例](#インデックス名をcityindexとしたときのデータ投入例)のように記述し（インデックス名はcityindexとする）、POSTを書いた行の再生ボタンを押してデータを入れてみる（Elasticsearchはデータ投入時に自動でmapping作成=RDBのテーブル定義をしてくれます）
8. ```GET cityindex/_search```で投入結果を確認する
9. インデックスの削除は、```DELETE cityindex```
10. データを複数投入する際は[下のデータ投入例](#インデックス名をcityindexとしたときのデータ投入例)の複数件データ投入の例
11. Mapping（＝RDBのテーブル定義）の確認は`GET cityindex/_mapping`
12. 手動でのマッピング定義は、[下のデータ投入例](#インデックス名をcityindexとしたときのデータ投入例)のmapping定義の例

### インデックス名をcityindexとしたときのデータ投入例

```json:1件データ投入
POST cityindex/_doc
{
  "cityname": "東京",
  "countryname": "日本",
  "Rank": "19",
  "population": "927"
}
```

```json:複数件データ投入
POST /cityindex/_bulk
{"index":{"_index":"cityindex"}}
{"cityname":"上海","countryname":"中国","rank":"1","population":"2415"}
{"index":{"_index":"cityindex"}}
{"cityname":"北京","countryname":"中国","rank":"2","population":"1861"}
{"index":{"_index":"cityindex"}}
{"cityname":"ムンバイ","countryname":"インド","rank":"3","population":"1839"}
{"index":{"_index":"cityindex"}}
{"cityname":"デリー","countryname":"インド","rank":"4","population":"1634"}
{"index":{"_index":"cityindex"}}
{"cityname":"カラチ","countryname":"パキスタン","rank":"5","population":"1491"}
{"index":{"_index":"cityindex"}}
{"cityname":"イスタンブール","countryname":"トルコ","rank":"6","population":"1464"}
{"index":{"_index":"cityindex"}}
{"cityname":"コルカタ","countryname":"インド","rank":"7","population":"1405"}
{"index":{"_index":"cityindex"}}
{"cityname":"ラゴス","countryname":"ナイジェリア","rank":"8","population":"1312"}
{"index":{"_index":"cityindex"}}
{"cityname":"モスクワ","countryname":"ロシア","rank":"9","population":"1222"}
{"index":{"_index":"cityindex"}}
{"cityname":"広州","countryname":"中国","rank":"10","population":"1208"}
```

```json:事前mapping定義
PUT cityindex
{
    "mappings" : {
      "properties" : {
        "cityname" : {
          "type" : "text"
        },
        "countryname" : {
          "type" : "text"
        },
        "rank" : {
          "type" : "integer"
        },
        "population" : {
          "type" : "integer"
        }
      }
    }
}
```

ここまで。
データ操作については、「[はじめての Elasticsearch](https://qiita.com/nskydiving/items/1c2dc4e0b9c98d164329)」等を参照。

# Amazon Elasticsearch Serviceとは
[Amazon Elasticsearch Service](https://aws.amazon.com/jp/elasticsearch-service/)は、AWSが提供するフルマネージドのElasticsearchサービスです。Elasticsearchを簡易に始めるには非常に便利です。Elasticsearchの特徴についてはこちらに詳しいです（[全文検索エンジン「Elasticsearch」を調べて使ってみた色々まとめ](https://vitalify.jp/blog/2017/02/elasticsearch_matome.html)）。Elasticsearchの様々な派生（Amazon Elasticsearch Serviceもその1つ）についてはこちら（[Amazon Elasticsearch Service の認証・認可に関する面倒くさい仕様をなるべくわかりやすく説明する](https://muziyoshiz.hatenablog.com/entry/2019/11/30/144213)）。

# 参考リンク
* [全文検索エンジン「Elasticsearch」を調べて使ってみた色々まとめ](https://vitalify.jp/blog/2017/02/elasticsearch_matome.html)
* [Amazon Elasticsearch Serviceを触ってみた](https://qiita.com/takayuki-miura0203/items/c2ad9527d818fd20ca93)
* [Amazon Elasticsearch Service の認証・認可に関する面倒くさい仕様をなるべくわかりやすく説明する](https://muziyoshiz.hatenablog.com/entry/2019/11/30/144213)
* [はじめての Elasticsearch](https://qiita.com/nskydiving/items/1c2dc4e0b9c98d164329)
* [Elasticsearch マッピング](https://medium.com/hello-elasticsearch/elasticsearch-9a8743746467)