Elasticsearchで検索エンジンの基本操作を行う

# はじめに
こんにちは[rilmayer](https://twitter.com/rilmayer_jp)です。
この記事はアドベントカレンダー「[Search&Discovery 全部俺](https://adventar.org/calendars/4691)」14日目の記事となります。

本日は定番のOSS全文検索エンジンである[Elasticsearch](https://www.elastic.co/jp/what-is/elasticsearch)の紹介をしたいと思います。
この記事では最低限の簡単な操作方法を紹介していきます。

[前回の記事](https://qiita.com/rilmayer/items/670e2a24fe16a00d1407)で紹介した全体像のうちの検索エンジンの一例です。

#Elasticsearchとは？
オープンソースの検索エンジンです。
スケーラビリティが高く大規模な検索システムを提供する際に用いられます。
また、検索システムのみならずログ等の分析用のデータストアとして用いられることも多々あります。
独特のクエリ形式（DSL）で検索を行います。

# 検索エンジンとしての基本的な操作を試してみる
## Elasticsearchの立ち上げ
やはりDockerが楽なのでDockerイメージで立ち上げてみます。
Elasticsearchは日本語のトークナイザーとしてプラグインのkuromojiが用意されているのでインストールしておきます。

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

以下のようにbuildしてrunすれば立ち上がります。

```bash
# build
docker build -t es .

# run
# 中に入る場合
docker run -it -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" es bash

# デーモンとして起動する場合
docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node"  es
```

ということで、 http://localhost:9200/ にアクセスすると起動中の情報が取得できます。
より詳細の情報を取得したい場合は[Kibana](https://www.elastic.co/jp/products/kibana)と連携するのが一般的です。


## Indexの作成・データの投入・検索
Elasticsearchではindex（今回の場合はデータベースのテーブルに相当）をまずはじめに作成する必要があります。

[以前の記事]()と同様、サンプルとしてアイドル検索をやってみます。
今回も操作スクリプトをPythonで書いてみました。pythonでは便利なライブラリがあるので今回はこちらを使います。

```bah
# インストール
pip install elasticsearch
```

### インデックス作成 wiht スキーマ定義
「アイドル名」と「アイドルの説明」の2つのフィールドを用意したスキーマを定義します。

```
from elasticsearch import Elasticsearch

# インスタンス生成
host = 'http://localhost:9200/'
es = Elasticsearch(host)
index_name = 'my_favorite_idols'
es.indices.create(index=index_name, body={
    'settings': {
            'number_of_shards': 5,
            'number_of_replicas': 0
    },
    'mappings': {
        'properties': {
            'idol_name': {
                'type': 'text',
                'analyzer': 'kuromoji'
            },
            'description': {
                'type': 'text',
                'analyzer': 'kuromoji'
            }
        }
    }
})
```

### データの追加
今回は件数が少ないので `index()` メソッドを用いてますが、bulk関数も用意されているのでitemの数が多くなっている場合はそちらを用いる方が良いかもしれません。

```python
# descriptionはwikipediaの該当ページから拝借
#   https://ja.wikipedia.org/wiki/AmiinA
#   https://ja.wikipedia.org/wiki/%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB%E3%83%BB
#   https://ja.wikipedia.org/wiki/%E3%83%A4%E3%81%AA%E3%81%93%E3%81%A8%E3%81%9D%E3%81%A3%E3%81%A8%E3%83%9F%E3%83%A5%E3%83%BC%E3%83%88
#   https://ja.wikipedia.org/wiki/BEYOOOOONDS
#   https://ja.wikipedia.org/wiki/TipToe.
items = [
    {
        "idol_name": "amiinA",
        "description": '雑誌「ニコ☆プチ」の読者モデルであった[1]amiと、miinaの2人で「  あみいな」を結成。「あみいな」は2人の名前「あみ」と「みいな」を掛け合わせたもの。\n\n2012年8月、当時同じ事務所のMYM Melodyが出演するイベントで初披露。\n\n結成当初は、ももいろクローバーZやAKB48などのカバーだったが、オリジナル曲を作る際にプロデューサーとして楽曲クリエイティブチーム・nanolineの齊藤州一が加わる[2]。\n\n2013年8月、初のシングル「1☆2☆3☆/マインドトラベル」を発売。アーティスト表記をアルファベットの「amiina」とする。\n\n2014年4月に吉田豪が「With you」（bayfm）[3]で、5月に南波一海がインターネット放送「南波一海のアイドル三十六房」[4]で「マインドトラベル」を紹介したことから、その頃から音楽に詳しいアイドルファンから反応が来るようになり、齊藤は「音楽的に自由に攻めてもいいのではないか」と思うようになったと語っている[5]。\n\n2016年2月13日のLIVEをもってmiinaが脱退[6]、活動休止となる。\n\n2016年3月22日、スタッフのTwitterで、表記を「amiinA」に変更し、新メンバーを加え活動を再開することを発表[7]。 5月3日、渋谷WWWで開催された「WonderTraveller!!! act.4」で、新メンバーmiyuが加入し、amiinAとして再始動[8]。\n\n2016年12月28日のライブをもち、miyuの高校受験のため活動を一時休止[9]。\n\n2017年4月15日よりライブ活動を再開[10]。\n\n新生amiinAは、「awake mind into ideal naked Avalon」の略。\n'
    },
    {
        "idol_name": "・・・・・・・・・",
        "description": '2016年4月に開催された「『女の子の東京をつくろう!!』プロジェクト アイドルオーディション」で選ばれたメンバーによるユニット[1][2]。\n\nコンセプトは「ポスト・ポケモンGO!時代のアイドル」「常に纏える(まとえる)アイドル」[3]「都市の幽霊」[4]。\n\n名前や顔を出さない、シューゲイザーやアンダーグラウンド・パンクなどを踏襲した楽曲、テクノロジーを用いた全く新しいアイドル活動などを特徴とする。\n\nライブのことを「観測」、ファンのことを「観測員」と呼ぶ。\n\nライブ中は写真撮影可能、動画撮影不可[5]。\n'
    },
    {
        "idol_name": "ヤなことそっとミュート",
        "description": 'BELLRING少女ハート→There There Theresの運営を手掛けたクリムゾン印刷による新アイドルプロジェクト。ただし、BELLRING少女ハートディレクターの田中紘治およびAqbiRecは運営には関与せず[1]、エンジニアの慎秀範（DCG代表）と林惇太、作曲家・アレンジャーのタニヤマヒロアキ（2019年離脱[注 1]）からなるチーム「DCG ENTERTAINMENT」がプロデュースを担っている[2]。\n\nコンセプトは「ヤなことだらけの日常をそっとミュートしても何も解決しないんだけど、とりあえずロックサウンドに切ないメロディーを乗せて歌ってみる事にする。」[3]。グランジやシューゲイザーといったオルタナティブ・ロックを主体とする。なお、タニヤマはヤナミューではマネージメントとパフォーマンスを主に担当[2]していたため、本職である作曲・編曲はオープニングSEの「ヤなことFriday」以外手がけていない。\n\nライブ中の写真撮影・動画撮影は原則として可能。リフト、ダイブ、サーフといった"人の上に乗る行為"は2017年4月29日以降禁止。\n'
    },
    {
        "idol_name": "BEYOOOOONDS",
        "description": 'ハロプロ研修生から選ばれたメンバーで結成されたユニット、CHICA#TETSU（チカ＃テツ）、雨ノ森 川海（あめのもり かわうみ）、および『ハロー!プロジェクト“ONLY YOU”オーディション』合格者により構成される[1]。\n「〜を超えて」「〜の向こう側へ」という意味の英単語「Beyond」をグループ名の語源とし、既成の枠組などを超えて、自由に未来へ大きくビヨーンと伸びていってほしいという思いが込められている。形を変幻自在にビヨーンびよーんと変貌させる、スライムのようなグループを目指す[1]。\nBEYOOOOONDSのリーダーは、2018年12月現在、公式には発表されていない。\n'
    },
    {
        "idol_name": "tipToe.",
        "description": '制作プロダクション合同会社SOVAの社内プロジェクトとして立ち上がり、2016年夏に行ったオーディション[1] で一般から選ばれたメンバーで結成。「みんなで青春しませんか？」をコンセプトに掲げ、青春や学校をモチーフとした楽曲やヴィジュアルが持ち味。メンバーは3年任期制で加入から3年で必ず卒業することになっている。\n\n統括及び音楽プロデューサーは音楽レーベル6jomaProject主宰の本間翔太。映像や衣装などを担当するヴィジュアルプロデューサーは写真家の長谷川圭佑。楽曲や振付などに自身もアーティストとして活動する若手クリエイターを数多く起用することも特徴。\n\n楽曲は、渋谷系ギターポップをベースにエレクトロニカ・チップチューンの要素を盛り込んだ爽やかでエモーショナルなものが多い。\n\nグループ名は「少しだけ背伸びして、今よりも高い所に届くように」という思いを込めて「背伸びする」(=「つま先で立つ」)を意味する英語「stand on tiptoe」から[2]。\n'
    },
]

# ドキュメントの登録
for item in items:
    es.index(index=index_name, body=item)
```

### データの検索
以下のようなコマンドで検索ができます。

```python
# 検索
query = 'メンバー'
es_query = {
    "query": {
        "multi_match": {
            "query":    query
        }
    }
}
results = es.search(index=index_name, body=es_query)

# 結果表示
print('hit:  ', results['hits']['total']['value'])
for i, result in enumerate(results['hits']['hits']):
    print(f"[{i}]",result['_source']['idol_name'], ':  ', result['_source']['description'][0:50])
```

結果は以下のような感じ。

```
hit:   4
[0] ・・・・・・・・・ :   2016年4月に開催された「『女の子の東京をつくろう!!』プロジェクト アイドルオーディション」で選
[1] BEYOOOOONDS :   ハロプロ研修生から選ばれたメンバーで結成されたユニット、CHICA#TETSU（チカ＃テツ）、雨ノ森
[2] amiinA :   雑誌「ニコ☆プチ」の読者モデルであった[1]amiと、miinaの2人で「  あみいな」を結成。「あ
[3] tipToe. :   制作プロダクション合同会社SOVAの社内プロジェクトとして立ち上がり、2016年夏に行ったオーディシ
```

# おわりに
今回はElasticsearchを検索サーバーとして使ってみるためのさわりを紹介してみました。
よく使われるOSSの検索エンジンでも操作方法に微妙な違いがあって、頭の切り替えが難しいですね。