データベース設計

フルテキスト検索 ふるてきすとけんさく

フルテキスト検索全文検索形態素解析トークナイズElasticsearch転置インデックス
フルテキスト検索について教えて

簡単に言うとこんな感じ!

フルテキスト検索は「本の内容を丸ごとスキャンして言葉を探してくれる検索エンジン」だよ!Googleで検索するとき、Webページの中の単語を探してくれるよね?あれをデータベースの文章データに対して行うのがフルテキスト検索なんだ。「LIKE検索」より格段に賢くて速い!


フルテキスト検索とは

フルテキスト検索(全文検索) とは、テキストデータの内容全体を対象に、特定の単語や語句を含む文書を高速に検索する技術です。通常のデータベース検索(LIKE '%キーワード%')と異なり、テキストをあらかじめ「単語単位」に分解しておく 転置インデックス(Inverted Index) を構築することで、膨大な文章の中からも高速に検索できます。

LIKE '%機械学習%' によるパターンマッチは「文字列が含まれるか」を1行ずつ調べる非効率な処理で、データが増えると急激に遅くなります。フルテキスト検索エンジンは文書をあらかじめ解析して「どの単語がどの文書に含まれるか」の索引(転置インデックス)を作成しておくため、検索が非常に高速かつ柔軟です。

日本語のフルテキスト検索では 形態素解析(文を意味のある最小単位の「形態素」に分割する処理)が必要です。「機械学習入門」を「機械・学習・入門」に分解してインデックスを作る処理で、MeCab・Sudachi などのライブラリが使われます。


主な実装方法と比較

方法技術特徴向くケース
DB組み込みFTSMySQL FULLTEXT / PostgreSQL tsvectorDBだけで完結小〜中規模、シンプルな全文検索
ElasticsearchApache Luceneベースの検索エンジン高機能・高速・スケーラブル大規模・複雑な検索要件
OpenSearchElasticsearchのフォーク(OSSライセンス)AWSが主導するElastic互換クラウド環境での全文検索
MeilisearchシンプルなOSS検索エンジン設定が簡単・日本語対応中規模サイトのサイト内検索
AlgoliaSaaSの検索プラットフォーム高速・高機能・料金が高めECサイト・SaaSプロダクト

LIKE検索とフルテキスト検索の速度差

テーブル: 100万件の記事、本文は平均1000文字

LIKE '%機械学習%' 検索:
  処理: 全100万行の本文を1行ずつスキャン
  時間: 数秒〜数十秒(データ量に比例して悪化)

フルテキスト検索(転置インデックス):
  処理: インデックスで「機械学習」を含む文書IDリストを参照
  時間: 数ミリ秒(データ量が増えても比較的安定)

歴史と背景

  • 1960年代 — Gerard Salton が情報検索理論「ベクトル空間モデル」を研究。検索の数学的基礎を構築
  • 1990年代 — インターネット普及でWebページの全文検索ニーズが急増。AltaVista・Yahoo など初期の検索エンジンが転置インデックスを実用化
  • 1999年 — MySQL 3.23 が FULLTEXT INDEX をサポート(MyISAMエンジン)
  • 2000年Apache LuceneJavaベースのOSS全文検索ライブラリとして公開。多数の検索エンジンの基盤に
  • 2010年Elasticsearch がLuceneベースのRESTful検索エンジンとして公開。分散処理・JSONインターフェースで急速に普及
  • 2012年 — PostgreSQL 9.2 が tsvectortsquery による本格的なFTSをサポート
  • 2021年 — Elasticのライセンス変更に伴い OpenSearch(AWSのフォーク版)が登場。クラウドでの全文検索が多様化

転置インデックスの仕組み

転置インデックスのイメージ 元の文書 記事1: 「機械学習でAIを作る方法」 → 機械 / 学習 / AI / 作る / 方法 記事2: 「深層学習とAIの関係」 → 深層 / 学習 / AI / 関係 記事3: 「機械設計の基礎知識」 → 機械 / 設計 / 基礎 / 知識 形態素解析で単語に分割 転置インデックス(単語→記事) 「機械」 → 記事1, 記事3 「学習」 → 記事1, 記事2 「AI」 → 記事1, 記事2 「深層」 → 記事2 「機械」検索→即座に記事1,3を返せる
-- MySQLでのフルテキスト検索
ALTER TABLE articles ADD FULLTEXT INDEX ft_content (title, body);
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('機械学習' IN BOOLEAN MODE);

-- PostgreSQLでのフルテキスト検索
CREATE INDEX idx_articles_fts ON articles
USING GIN(to_tsvector('japanese', title || ' ' || body));
SELECT * FROM articles
WHERE to_tsvector('japanese', title || ' ' || body) @@ to_tsquery('japanese', '機械学習');

関連する規格・RFC

規格・RFC番号内容
ISO/IEC 9075-2 (SQL:2003)CONTAINSFREETEXT など全文検索関数の標準仕様

関連用語