ElasticSearch の基本概念を整理する

# 前提
- ElasticSearch 7 系
    - 7.17 想定

# 概要
- **Elasticsearch は、高スケーラブルな全文検索ソフトウェア**
    - 全文検索とは、複数の文書を対象として、特定の文字列が含まれる文書を探す技術のこと
        - RDB との大きな違いとしては、検索条件にどの程度合致しているかがスコアで数値化されること
            - RDB は`検索条件に合致するデータを全て取得する`一方、全文検索では`スコアを利用して最も検索条件に合致するデータを取得できる`
            - また、全文検索では、検索処理のユースケースを主用途としているため、クエリ性能・スケーラビリティが相対的に重視されている
    - ショッピングサイトの商品検索のような大規模なデータ検索に使われる
        - その他にもログ分析などの幅広い用途で使われる
- 実際に内部で検索を行っているのは、Apache Lucene という検索ライブラリ
    - コアとなる機能は検索ライブラリに移譲している
        - インデックス作成や検索処理
    - **Elasticsearch 自体は検索サーバとして、検索ライブラリの補完機能を提供する**
        - REST API 提供やクラスタ管理等

# 特徴
- **転置インデックスによって、全文検索を実現**
    - `ドキュメント内に含まれる各単語`と`そのドキュメント`の組み合わせをインデックスとして構成する
        - フォーマット: `単語 -> ドキュメント, 単語の出現位置`
    - 検索の流れとしては、該当単語を含むドキュメントを選定した後、出現位置条件の評価を行う
- **分散配置によって、高パフォーマンス&高可用性を実現**
    - 具体的には、シャード&レプリカ
    - シャードは、インデックスの分割単位（`書き込み可能`）
        - インデックスのデータを一定数に分割して、異なるノードで分散保持する
        - 演算処理を複数ノードで分散・並列化することでパフォーマンス改善
        - シャード数は、インデックス作成時に決定後、変更できない
    - レプリカは、シャードの複製（`読み取り専用`）
        - オリジナルをプライマリシャード、複製をレプリカシャードと呼ぶ
        - フェイルオーバーによる高可用性、及び検索分散によるパフォーマンス改善
        - レプリカ数は、後から変更できる
    - デフォルトでは、各インデックスに1つのシャードと1つのレプリカが割り当てられる
        - 1つのプライマリシャードと1つのレプリカシャードの計2シャード
        - [推奨シャードサイズは 10〜50GB](https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/sizing-domains.html#:~:text=%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AA%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A8%E3%81%97%E3%81%A6%E3%80%81%E6%A4%9C%E7%B4%A2%E3%83%AC%E3%82%A4%E3%83%86%E3%83%B3%E3%82%B7%E3%83%BC%E3%81%8C%E4%B8%BB%E8%A6%81%E3%81%AA%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E7%9B%AE%E6%A8%99%E3%81%A7%E3%81%82%E3%82%8B%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%AF%E3%82%B7%E3%83%A3%E3%83%BC%E3%83%89%E3%81%AE%E3%82%B5%E3%82%A4%E3%82%BA%E3%82%92%2010%EF%BD%9E30%20GiB%E3%80%81%E3%83%AD%E3%82%B0%E5%88%86%E6%9E%90%E3%81%AA%E3%81%A9%E3%81%AE%E6%9B%B8%E3%81%8D%E8%BE%BC%E3%81%BF%E3%81%8C%E5%A4%9A%E3%81%84%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%81%AF%2030%EF%BD%9E50%20GiB%20%E3%81%AE%E7%AF%84%E5%9B%B2%E3%81%AB%E7%B6%AD%E6%8C%81%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%92%E3%81%8A%E5%8B%A7%E3%82%81%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
- REST API によって、直感的なアクセス方法を実現
    - URL を見るだけで、`何`を`どうする`のか理解できる
        - 処理対象のリソースは、URI で一意に表現する
        - リソースに対する操作は、HTTP メソッドで表現する
    - また、REST API を扱えるツールは数多く公開されているため、容易に実利用できる
    - ちなみに、Apache Lucene は Java API を利用する必要がある
- JSON フォーマットの採用によって、柔軟性の高さを実現
    - インデックス作成・検索対象のドキュメントは全て JSON フォーマットで表現される
    - ドキュメントは事前にスキーマ定義しなくても格納できる
        - JSON として表現されていれば、ドキュメント格納時に自動的にスキーマを推論してくれる


# 構成要素
RDB との比較を交えながら見てみる

|ES 要素  |概要  |RDB 類似要素  |
|---|---|---|
|クラスタ |ノードの集合体。全ノードに対して、統合したインデキシング機能と検索機能を提供する。  | -
|ノード |クラスタに含まれる単体サーバ。具体的には、ElasticSearch が動作する 1 つの JVM インスタンスのこと。1 つの OS 上に複数ノードを起動することも可能。<br>[ノードには、各役割に応じた種別がある。](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-node.html#node-roles)例えば、Master/Data/Ingest/Coordinating/... ノードがある。詳細はまた別途行う予定（各ノード間の連携の話とか）。デフォルトの設定では、各ノードがほぼ全ての役割を持つ。大規模構成の場合は、役割毎に専用ノードを構成することもある。  | -
|インデックス | ドキュメントを保存する場所。実際には、シャードによって、各ノードに分散して格納されている。 | テーブル（or データベース）
| ドキュメントタイプ | ドキュメントがどのようなフィールドから構成されているのかを表す概念。ドキュメントに含まれるフィールドの型や属性情報などのデータ構造が定義される。**1インデックスにつき1ドキュメントタイプだけ定義できる※。**<br>また、それを具体的に定義したものをマッピングと呼ぶ。なお、事前にマッピングが定義されていない場合は、ElasticSearch 側で自動的にマッピング定義してからインデックス作成を行う。 |テーブル定義
|ドキュメント  | インデックス作成/検索の基本単位。JSON 形式で保存される。1つ以上のフィールドから構成される。 |レコード
|フィールド  | ドキュメント内の項目名・値の組。例えば、`"name": "taro"`が1フィールドになる。<br>転置インデックスはフィールド毎に作成・管理されているため、クエリ実行時はフィールド単位で検索を行う。<br>フィールドの値にはいくつかのデータ型が用意されている。例えば、文字列のデータ型として、text や keyword がある。詳細はまた別途行う予定（アナライザの話とか）。 |カラム


- ※ 元々、一つのインデックス配下に複数のドキュメントタイプを定義できた
    - [ver7 以降は前述の通り制限されることになった](https://www.elastic.co/guide/en/elasticsearch/reference/7.17/removal-of-types.html)
        - ドキュメントタイプに対するミスリードが起こす弊害を防ぐため
            - 同インデックス内の別ドキュメントタイプの同名フィールドは物理的に共有されている
            - 別テーブルの同名カラムのように独立しているものと扱おうとすると、、
                - 同名フィールドを削除する時や同名フィールドを別インデックスに配置する時など

---

それぞれの要素の関連性を可視化してみる

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627625/33c8f762-8106-54c7-c459-2f486f1a365d.png" width=80%>


# 参考
- [PayPayにおけるElasticsearchの核心](https://blog.paypay.ne.jp/elasticsearch-at-paypay/)
- [データベースとしてのElasticsearch](https://qiita.com/rjkuro/items/95f71ad522226dc381c8)
- [Elasticsearch実践ガイド](https://www.amazon.co.jp/Elasticsearch%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-impress-top-gear-%E6%83%A3%E9%81%93/dp/4295003913)