よくある検索システムの構成と使われるアプリケーション例

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

今日はよくある一般的な検索システムの構成について簡単に説明しつつ、それぞれのコンポーネントが何をやっているか、それぞれのコンポーネントを担う代表的なアプリケーションについて紹介したいと思います。

# 検索システムの構成
「[AIアルゴリズムマーケティング 自動化のための機械学習](https://amzn.to/2P5uHEU)」を参考にしていますが、以下のような形が一般的かなと思います。
![note_表紙.040.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108223/2a0726b2-297b-9a5c-fe62-9ecb2fad774f.jpeg)

以下、それぞれの部品っぽいものをコンポーネントとして、どんな働きをするかというのと、実際にどんなアプリケーションで実現できるかというのを紹介していきます。

## インターフェース
検索システムでユーザーが直接操作して結果を受け取る部分です。
例えば、Googleだと「検索窓のページ」と「検索結果一覧ページ」がインターフェースに当たります。
Googleの場合は検索結果一覧ページの中に「情報をまとめたカード」や「知事情報」等の複数の見せ方が存在しています。

### インターフェースを実現する技術
ここはWebアプリだったり、スマホアプリだったり、デスクトップアプリだったりと色々あります。
UI（画面操作）に限らずCUI（文字入力操作）のインターフェースもありえます。

裏側の検索サーバーと通信ができれば、Javascriptなど（Webアプリ）、iOSなど（スマホアプリ）、シェルスクリプトなど（CUI）色々あります。

## 検索エンジン
ここが検索システムの心臓部です。
インターフェースで入力されたクエリを解釈して、インデックスされたアイテムから適切なアイテムを取得し並び替えてユーザーに提供します。
ランキングを最適化する場合も

### 検索エンジンを実現する技術
以下のような観点で有名な技術があります。
プログラムに組み込んで使うライブラリと、それ単体でほとんど全ての機能を賄う検索エンジンアプリケーションがあります。また、検索の結果をユーザー行動等の学習に応じて並び替えるランキングを行うためのライブラリなども利用することができます。

- 全文検索ライブラリ
  - [Lucene](https://lucene.apache.org/) ... JAVAのテキスト検索ライブラリー
  - [Whoosh](https://bitbucket.org/mchaput/whoosh/wiki/Home) ... Pythonによるテキスト検索ライブラリー
- OSS全文検索エンジン
  - [Solr](https://lucene.apache.org/solr/) ... OSSの全文検索システム
  - [Elasticsearch](https://www.elastic.co/jp/what-is/elasticsearch) ...Elastic社が中心になって開発が進められているOSSの全文検索システム
  - [Groonga](http://groonga.org/ja/) ... オープンソースのカラムストア機能付き全文検索エンジン
- 検索エンジンアプリケーション
    - [Algolia](https://www.algolia.com/) ... 検索アプリケーションを提供しているWebアプリ。API等で利用できる
    - [Azure Cognitive Search](https://docs.microsoft.com/ja-jp/azure/search/search-what-is-azure-search) ... Microsoftが提供する全文検索アプリケーション

ちなみに、ElasticsearchはAWSやAlibaba CloudなどでフルマネージドなSaaSとして提供されていたりします。

## インデクシング
アイテムの更新頻度が低かったり、定期的にまとめて更新すれば良い場合バッチシステムなどが利用されます。
図書館など週に1度本が納入されるなどアイテム更新が決まっている場合などがこれに当たります。

また、リアルタイムの更新が必要検索システムの場合は逐次更新のため差分検知によるインデクシングや、データが追加されるたびにオンラインのインデクシングが必要です。

### インデクシングを実現する技術
- バッチシステム
  - 定期実行 ... [crontab](https://eng-entrance.com/linux-command-crontab)、[kubernetes cron job](https://kubernetes.io/ja/docs/concepts/workloads/controllers/cron-jobs/)など
  - ワークフローエンジン ... [Airflow](https://airflow.apache.org/)(GCPだと[Cloud Composer](https://cloud.google.com/composer/?hl=ja))、[Rundeck](https://www.rundeck.com/open-source)など
- オンラインインデクシング
  - ストリーミング処理 ... [Apache Beam](https://beam.apache.org/)など
  - データパイプライン（クラウド） ... [Cloud pub/sub](https://cloud.google.com/pubsub/docs/overview?hl=ja)+[Cloud Dataflow](https://cloud.google.com/dataflow/?hl=ja)や[Amazon Kinesis](https://aws.amazon.com/jp/kinesis/)など
- RDMSによるアドアン機能
  - [MySQL](https://www.mysql.com/jp/)や[PostgreSQL](https://www.postgresql.org/)など

## アイテムデータベース
アイテム情報が入っているデータベースです。
こちらもインターフェース同様に様々な技術が用いられています。
ここでは紹介を省略します。

こちらのデータベースの種類などに関する記事がおすすめです。
https://engineer-club.jp/type-of-database

## 検索履歴
検索の履歴を管理するシステムです。
このシステムはデータを貯める「ストレージ」と逐次データをストレージに書き込む「データパイプライン」の2つのコンポーネントからなります。

### 検索履歴管理を実現する技術

- ストレージ
  - データベースやファイルストレージが用いられますが、データの特性やクラウド活用の観点から、データベースとして[BigQuery](https://cloud.google.com/bigquery/?hl=ja)や[Redshift](https://aws.amazon.com/jp/redshift/)、ファイルストレージとして[Cloud Strage](https://cloud.google.com/storage/?hl=ja)や[Amazon S3](https://aws.amazon.com/jp/s3/)などが用いられることが多いです
  - 実はElasticsearchは検索履歴等のストレージとして使うことも可能であり、よく使われています
- データパイプライン
  - [Fluentd](https://www.fluentd.org/) ... データパイプライン用のライブラリ
  - [Amazon Kinesis](https://aws.amazon.com/jp/kinesis/) ... リアルタイムデータのストリーム処理ができる

## 分析ツール
こちらも検索履歴と同様にパイプラインとストレージに分けられますが、分析ツールの場合通常これにBIツールと呼ばれる可視化ツールが用いられます。
また、分析を行う際に統計解析が行われたりもします。

### 分析ツールを実現する技術
- データパイプライン
  - 基本的に検索履歴と同様です
- ストレージ
  - 毎回計算し直すのが大変な分析などは途中集計の結果をストレージなどに保管します
- 分析ツール
  - モニタリングツール
    - [Metabase](https://www.metabase.com/) ... OSSのデータ可視化ツール
    - [Kibana](https://www.elastic.co/jp/products/kibana) ... Elasticsearchでの利用に特化しした可視化ツール
    - [Looker](https://ja.looker.com/) ... Webアプリケーションとして利用できるビジネスインテリジェンスソフトウェア

## データ活用基盤・検索補助補正情報
これらについて主に機械学習等による検索体験の向上を目指すコンポーネントです。
例えば、検索履歴を元に検索サジェストを行ったり、ユーザーの行動履歴を元によりユーザーにとって良いランキングを補助したり、インデクシングの際に重要な単語の重みを上げたりまたは不要な単語を取り除いたりといったことを行います。
そのため、作成したモデルやデータをロードして活用することができる検索エンジンを用意することが必要です。

### データ活用基盤・検索補助補正情報を実現する技術
- 検索補助のためのデータ集約
  - 各種データ集約アプリケーションなど
- 検索補正のための技術
  - 各種機械学習ライブラリなど


# おわりに
本日は検索エンジンを作っていく場合にどんな部品が必要になっていくかを考えてみました。
最後にはなりますが検索エンジンの構成で「これが絶対正解！」というものはありませんので、関わるサービスの特徴やコンポーネントのアプリ特性を把握しながら柔軟に構築していけると良いかもしれません。