elasticsearshをもっとちゃんとやってみる

前に Elasticsearch 触ってみたけど、本当に触るだけで具体的に何も使わなかったよ。
その時作った環境も捨てちゃったから、新たに環境作る所からトライだ。

【今回の目標】

- Docker で環境作ってみる。
- データを全文検索してみる。

今回はお店の商品を検索するようなシステムを想定するよ。

- お店の名前から取扱商品の一覧がわかる
- 商品名から取り扱っているお店がわかる

# 1.Docker で Elasticsearch(とついでに Kibana)を構築する。

他の秘密の開発に絡めたいから、敢えて Virtualbox に構築した Rocky Linux に Docker 仕込むよ。Rocky Linux のフォルダ構成はこんな感じだ。

```
usr ─ share ─ els ┬ elasticsearch ─ Dockerfile
                  ├ kibana ─ Dockerfile
                  └ docker-compose.yml
```

Elasticsearch と Kibana ディレクトリに Dockerfile を作って、それを docker-compose.yml から呼ぶ感じにするよ。それぞれこんな内容だよ。

```Dockerfile:elasticsearchのDockerfile
FROM docker.elastic.co/elasticsearch/elasticsearch:8.4.1
RUN elasticsearch-plugin install analysis-kuromoji
```

```Dockerfile:kibanaのDockerfile
FROM docker.elastic.co/kibana/kibana:8.4.1
```

```yml:docker-compose.yml
version: "3"

services:
  elasticsearch:
    build: elasticsearch
    volumes:
      - elasticsearch-data:/usr/share/els/elasticsearch/data
    ports:
      - 9200:9200
    expose:
      - 9300
    environment:
      - discovery.type=single-node
  kibana:
    build: kibana
    volumes:
      - ./kibana.yml:/usr/share/els/kibana/kibana.yml
    ports:
      - 5601:5601

volumes:
  elasticsearch-data:
    driver: local
```

テスト用だからシングルノードにしているよ。
ちなみに Kibana の設定で volumes を指定しているけど、これをしておかないと Kibana を最初に立ち上げたときの設定が一生上手く入らなかった。[公式](https://www.elastic.co/guide/en/kibana/current/docker.html)でようやく見つけたよ。
ここまで作ったら、 `/usr/share/els` フォルダで `docker-compose up -d` を実行する。
立ち上がるの時間がかかるから、ちょっと待ってかた 5601 ポートにブラウザでアクセスすると、kibana の画面が立ち上がるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/8e0ba6e4-795e-1afb-185f-89879e244901.png)
enrollment token を入れろって言われる。enrollment token はコマンド入れて取得するよ。基本的に[公式](https://www.elastic.co/guide/en/kibana/current/docker.html)に書いてある通りだ。

```cmd
docker exec -it els-elasticsearch-1 /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
```

コマンド入れると 3 行くらい謎の文字列が表示されるので、これをコピペで張り付けて「Configre Elastic」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/bd2affec-8068-9563-75cb-55415ce9aa96.png)
そうするとまた謎の入力画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/258d5eb8-cbca-0b7e-2f58-d72ae9dc9b53.png)
認証しろって言われているようだ。これもまた docker exec で画面に出ているコマンド入れてみる。

```cmd
docker exec -it els-kibana-1 /usr/share/kibana/bin/kibana-verification-code
```

「.bat」はいらないから注意。
コマンドを入れると謎の 6 桁の数字が表示されるので、これを入力して「Verify」をクリックする。
そうすると、なんかやってまっせ的な画面が表示されたあと、ログイン画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/edeee8f0-3154-08f3-677a-16fc6869f4ce.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/650984e2-fd77-0fad-d803-66ca704d5548.png)
Username ってなんだ。
どうやら Username は elastic らしいよ[by 公式。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/258d5eb8-cbca-0b7e-2f58-d72ae9dc9b53.png)結局なんでも公式見ないとわからないね。
公式には「パスワードリセットしたかったらこうしとけよ」みたいなことが書いてあるので、Docker exec でコマンド入れてみる。

```cms
docker exec -it els-elasticsearch-1 /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic
```

そうすると「やってもいい？」みないな聞かれ方するので、勇気をもって y を入れると、新しいパスワードが表示される。
これもコピペで入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/5c936692-2b20-bd13-0c27-7bb88af550db.png)
それで「Log in」をクリックする。それ。
すると、kibana の画面が開くよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/e2026e17-2998-83bc-bbdb-1969a6b8fbae.png)
これで Elasticsearch と Kibana が使えるようになった。

# 2.データを入れてみる

さて、今回試すのは、最初に書いた通り、お店と商品の関連を検索するものだ。
こんなイメージのデータを作るよ。

| お店         | 商品                 |  価格 |
| :----------- | :------------------- | ----: |
| 吉野家       | 牛丼                 |   426 |
|              | 月見牛とじ御膳       |   712 |
|              | 月見牛とじ丼         |   602 |
|              | 豚丼                 |   393 |
|              | 牛黒カレー           |   547 |
|              | 鰻重                 | 1,097 |
| すき家       | 牛丼                 |   400 |
|              | すきやき牛丼         |   580 |
|              | 豚生姜焼き丼         |   580 |
|              | うな丼               |   950 |
|              | ほろほろチキンカレー |   680 |
| マクドナルド | こく旨すき焼き月見   |   440 |
|              | ビッグマック         |   390 |
|              | 月見マフィン         |   340 |
|              | マックフライポテト   |   150 |

[公式ドキュメント](https://www.elastic.co/guide/en/app-search/8.4/indexing-documents-guide.html)見ても、微妙な書き方でわかりづらい。誰かのまとめ記事読んだほうがわかりやすいよ。
よく言われるのは RDB に例えると index がテーブルで、document がレコードという感じみたいだ。
いきなり document を登録すると全部 text で登録するらしい。属性指定したかったら schema で定義するらしい。
コマンドでいれる方法はいろんなところに書いてあったから、kibana から csv でデータ投入する方法を書いてみるよ。
①kibana の左メニュー「Management」の「integretions」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/e53e7aec-6765-eb72-a01b-3d55b6612610.png)
②Integretions の左メニューを下スクロースしていくと、「Upload a file」というメニューがある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/a603df35-613a-9f84-d2ef-ebdfe350937f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/dc27e6ba-034f-52a0-a2b0-1c723a9859b5.png)
③「Upload a file」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/d87d9005-add6-a3f0-54d2-438bc6c9a034.png)
④ アップロードする画面が表示される。画面下にある「Select or drag and drop afile」のところに csv ファイルをドラッグ＆ドロップする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/51324691-2fb2-906d-f208-3396a02f23f9.png)
⑤ ファイルの中身が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/ef3ae88b-25d3-175c-8d5a-ce1636d10569.png)
⑥ 項目は全部 keyword で定義されるらしい。とりあえずこのまま「Import」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/abfdd765-b5f7-aaf3-cf78-0cd7f3d82bf6.png)
⑦ インデックス名を入れろ、と言われるので、適当に入れてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/5cd38947-fe33-b555-cb07-27875615571e.png)
⑧ 「Import」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/07dbe220-fb51-a704-5aec-98369a30019f.png)
⑨ 下に結果が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/15913cf5-27ab-4372-f2eb-00df71b7877d.png)
試しに「View index in Discover」をクリックしてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/0c465a93-ca98-f586-14cb-4bfcd12e51be.png)
なんか入ったっぽいよ。

# 3.データを検索してみる

このまま Kibana で確認するよ。コマンドで知りたい人は他のページを検索だ。
①kibana の左メニューから「Analytics」の「Discover」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/b7b5fc7c-8d61-b3e4-3d4e-136c98057d36.png)
② さっき登録したデータが表示されている。複数インデックスが登録されている場合は左上のドロップダウンで index を選択できるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/77eb2e5d-6f5a-0718-247b-42fd25812590.png)
③ 上のほうにコマンド入力できるエリアがあるから、ここに検索条件を入れる。
例えば「店:吉野家」で検索すると、店に「吉野家」が設定されたデータだけ表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/e574d19a-da55-8de8-c620-660f9fc89f92.png)
④ ワイルドカードは\*、1 文字なら?。Windows コマンドと一緒だね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/46eff3d0-65f7-5bca-11c9-d969a652a14a.png)
⑤ 演算子も普通に使えるっぽい。単価が 400 円以上 600 円未満ならこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137858/1fe1f7eb-e536-dd48-c7e2-1255d19a85ac.png)
いずれこれを Flutter で見れるようにしよう。そう、いつか、きっと…
その時まで、アリヴェデルチ！

# 4.Appendix curl でアクセスしようとしたら、ver8 だったよ

いろんなサイトを見ると、Kibana でなくて curl でアクセスしている例が多いから、試しに curl でコマンド入れてみたら！なんとエラーになったよ。

```cmd
[root@localhost els]# curl -X GET 'http://localhost:9200/_cat/nodes?v'
curl: (52) Empty reply from server
```

こんな感じ。
なぜだ。Kibana ではアクセスできるのに。
いろいろ検索したら、ようやく[【Ubuntu】Elasticsearch 8 のインストール](https://self-development.info/%E3%80%90ubuntu%E3%80%91elasticsearch-8%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)にヒントが書いてあったのを見つけたよ。ありがとうございます！
Elasticsearch の ver8 はセキュリティが強化されていて、SSL やら TLS やら設定されていて、curl コマンドそのまま打ってもエラーになるらしい。
コマンドを入れるときに SSL 証明書の在処を指定して、ログイン ID も指定して、パスワード入れると始めてコマンドが効くらしい。
Docker の SSL 証明書の在処は、Elasticsearch のコンテナ内の elasticsearch.yml の中に書いてあった。
フルパスでいうと、こんな感じ。
/usr/share/elasticsearch/config/certs
SSL 証明書のファイル名は「http.p12」だ。
コマンドにすると、こんな感じ。

```cmd
curl -k --cacert /usr/share/elasticsearch/config/certs/http.p12 -u elastic 'https://localhost:9200/_cat/nodes?v'
```

コマンドを入力すると、elastic のパスワードを入力しろと言われるから、パスワードを入れてやるとコマンドが実行されるよ。

```cmd
[root@localhost els]# curl -k --cacert /usr/share/elasticsearch/config/certs/http.p12 -u elastic 'https://localhost:9200/_cat/nodes?v'
Enter host password for user 'elastic':
ip         heap.percent ram.percent cpu load_1m load_5m load_15m node.role   master name
172.22.0.2           16          96  99    5.35    4.55     3.27 cdfhilmrstw *      e075949f53f7
```

やれやれ、ここまでたどり着くのに結構時間かかっちゃったよ。セキュリティ強化されて使い方わかんなくなるのって、結構あるあるだよね。
そんだば、いつかまた。チャォウ！