Elasticsearchについての解像度を高めてみた

## はじめに
日々、システム開発に奮闘しているフリーランスエンジニアです。
今回は今携わっている業務の中でElasticsearchの仕組みを理解しないと難しそうなものがあったので、この機会にElasticsearchがどのようなシステムなのか、その利用方法について今までふわっとしていたものをもう少し具体的にまとめてみようと思います。


## Elasticsearchとは

> Elasticsearchは、様々なユースケースを解決する分散型RESTful検索/分析エンジンです。データを一元的に格納することで、超高速検索や、関連性の細かな調整、パワフルな分析が大規模に、手軽に実行可能になります。Elastic Stackの心臓部となるプロダクトです。

https://www.elastic.co/jp/elasticsearch


うーん、これだけだととりあえず検索と分析ができるすごいシステムなんだくらいしか分からないかもしれない。もう少し検索にまつわる領域について深ぼってみよう。

## そもそも検索システムとは
検索システムとは、検索キーワードに該当する文書を見つけ出すシステムのことです。例えばメルカリを考えてみましょう。
メルカリにはたくさんのユーザーから大量の商品が出品され、その商品を購入するユーザーが存在します。この時に、数百万〜数千万個ある商品の中から何もヒントがない状態で自分が欲しい商品を探し出すのはかなり難しいです。このような時に検索システムが活用されます。

つまり、検索システムとはユーザーが膨大なデータの中から欲しい情報を探し出すためのツールと言えます。

### どのような検索方法があるのか

一般的には複数の文書の集合からある検索ワードにマッチする文書を探すことを全文検索と言います。この検索には大きく分けて2つの検索種類があります。

#### 1:逐次検索
逐次検索は文書全体を順番にみていく方法なので、文書の量が多いと比例して探し出すのに時間がかかります。特定のディレクトリ配下で「log」をgrepすると、ディレクトリ内の一番上からgrepされた箇所がターミナルに表示されるのと同じようなイメージです。

#### 2:インデックスを用いた検索
対して、インデックス検索では文書全体を見るわけではないので、検索時間が短縮されます。辞書の索引から調べるとその検索ワードが何ページに記載されているかが分かると同じイメージです。

## 転置インデックス
この全文検索に利用されるインデックスは、一般的には転置インデックスが利用されます。転置インデックスとは文書の集合から単語をかき集めて、その単語がどの文書に表れているのかをリスト化した情報をデータベースに入れ、検索時に該当のデータを高速で取得するための仕組みです。

具体的なイメージはCoWorkerの佐藤さんのyoutubeで公開されていたイメージが分かりやすかったので、活用させていただきます。

> 例えば、以下のような文書集合があったとします。
>
> 文書1: ノーム・チョムスキーとは、アメリカの学者である
文書2: アルベルト・アインシュタインとは、ドイツの学者である
文書3: グラハム・ベルとは、スコットランドの発明家である。
日本語の文章の転置インデックスを構築するには、まず形態素解析を行いキーワードを区切ってあげる必要があります。
>
> 形態素解析を通した後の文書は以下のようになります。
>
> 文書番号	文章
文書1	ノーム・チョムスキー/とは/アメリカ/の/学者/である
文書2	アルベルト・アインシュタイン/とは、/ドイツ/の/学者/である/
文書3	/グラハム・ベル/とは/スコットランド/の/発明家/である/
>
>検索に利用しない助詞などを取り除くと次のようになります。
>
> 文書番号	文章
文書1	ノーム・チョムスキー/アメリカ/学者/
文書2	アルベルト・アインシュタイン/ドイツ/学者/
文書3	/グラハム・ベル/スコットランド/発明家/
上記の情報を利用して、転置インデックスを構築すると以下のようになります。
>
> キーワード	文書番号
ノーム・チョムスキー	文書1
アメリカ	文書1
学者	文書1, 文書2
アルベルト・アインシュタイン	文書2
ドイツ	文書2
グラハム・ベル	文書3
スコットランド	文書3
発明家	文書3
>
>「チョスキーって誰だっけ？」と言う検索ワードを検索システムに問い合わせてみます。 検索システムに問い合わせる検索ワードのことを、「検索クエリ」と呼びます。
>
> このクエリを、インデックスと同じように形態素解析してあげます。
>
> チョムスキー
誰
>
>下記の転置インデックス表から、この2つのうちどちらかが含まれているのは、文書1ということがわかります。

![スクリーンショット 2024-02-06 22.24.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2732316/ab85850f-f25a-0773-957d-799b01df2eec.png)

参考：https://www.youtube.com/watch?v=FqABNJ6fGXQ

Elasticsearchもこの転置インデックスを利用しています。

## Elasticsearchの立ち位置
当然この検索システムはElasticsearchだけでは成り立ちません。なぜなら、Elasticsearchは検索処理を高速化させるためのツールであって、この中に元からデータが入るわけでも自然に入るわけでもないからです。そのため、このツールを入れた検索システムの構築が必要になってくるわけです。必要になってくるのはElasticesearchに「データを登録する処理」と「特定のデータをリクエストする処理」の2つになります。

### ①データを登録する
まずはElasticesearchにデータを登録します。まずはクローラーを使って、csvなどのドキュメントデータやDBからデータをクローリングして自社のDBにデータを登録します。その後、Indexerという検索エンジンにデータを登録する仕組みが存在しておりPOSTリクエストによって、検索エンジン（ここでいうElasticsearch）に整形された形で登録されます。

### ②特定のデータをリクエストする
次にElasticsearchに特定のデータを取得するように指示を出します。当然、特定のデータを絞り込むリクエストパラメータをElasticsearch自体は持っていないので、リクエストを送る前に、必要なデータを取得するための条件をAPI上で作成しておく必要があります。

この①と②のシステムをElasticsearchを交えて構築することで、初めて高速な検索システムは実現します。

## Elasticsearchの利用方法について
先ほど紹介したcoWorkerの佐藤さんがgithubに環境構築から実際の利用イメージまで丁寧に記載してくれていますので、こちらを参考にしてみてください。

https://github.com/coworker-jp/search-doc/blob/master/doc/03-Elasticsearch%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95.md

## まとめ
転置インデックスを理解したことによって、なぜわざわざDBではなくElasticsearchを利用する必要があるのかを少しは理解できた気がします。ただkibanaというGUIを利用できるにしても、わざわざPOST、PUT、GETのリクエストを書き、登録時には指定のJSON形式で記載する必要があり、少し直感的な利用はしづらいイメージがあるなと感じました。いやいや、もっと簡単に利用できる方法があるよという方はぜひご教示いただければ幸いです！