PostgreSQLでn高速・高機能な日本語n全文検索¶ ↑
: author
堀本泰弘
: institution
株式会社クリアコード
: content-source
July Tech Festa 2021 winter
: date
2021-01-24
: allotted-time
20m
: start-time
2021-01-24T14:20:00+09:00
: end-time
2021-01-24T14:40:00+09:00
: theme
.
自己紹介¶ ↑
# image # src = images/self-introduction.png # relative_height = 107
今日のテーマ¶ ↑
PostgreSQLでn((*高速*))・((*高機能*))な日本語全文検索nを実現する
今日のテーマ¶ ↑
…の前に
全文検索?¶ ↑
全文検索?¶ ↑
((*全*))ての((*文*))書から特定の文字列をn((*検索*))する
全文検索?¶ ↑
# image # src = images/web-search.png # relative_height = 87
全文検索?¶ ↑
# coderay shell % grep PGroonga ./* ./docker-compose.yml: PGroonga: ./docker-compose.yml: POSTGRES_DB: PGroonga ./docker-compose.yml: POSTGRES_PASSWORD: PGroonga ./docker-compose.yml: POSTGRES_USER: PGroonga
全文検索の対象¶ ↑
(('tag:center')) (('tag:large')) (('tag:margin-bottom * 2')) 大量のテキスト
* 例:Redmineのwiki・チケット * 例:チャットログ * 例:口コミ
PostgreSQLの全文検索¶ ↑
-
LIKE:組み込み
-
textsearch:組み込み
-
pg_trgm:標準添付
-
pg_bigm:プラグイン
-
PGroonga:プラグイン
PostgreSQLの全文検索¶ ↑
-
((LIKE)):組み込み
-
((textsearch)):組み込み
-
pg_trgm:標準添付
-
pg_bigm:プラグイン
-
((PGroonga)):プラグイン
参考¶ ↑
-
pg_trgmとpg_bigmとPGroongaの比較は以下の記事を参照
PostgreSQLの全文検索¶ ↑
# RT delimiter = [|] 名前 | 日本語 | 速度 | 機能 LIKE | ○ | △ | ☓ textsearch | ☓ | ○ | △ PGroonga | ○ | ○ | ○
LIKE¶ ↑
-
メリット
-
標準で使える
-
インデックス作成不要(データ更新が遅くならない)
-
データが少なければ十分高速
-
LIKE¶ ↑
-
デメリット
-
データ量に比例して遅くなる
-
類似文書検索、同義語検索等の便利な機能はない
-
textsearch¶ ↑
-
メリット
-
標準で使える
-
インデックスを作成するので、データ量が多くても高速
-
同義語検索、検索結果のランキング、結果のハイライトなど、便利な機能がある
-
textsearch¶ ↑
-
デメリット
-
言語毎にモジュールが必要
-
英語やフランス語のモジュールは組み込み
-
日本語は別途インストールが必要
-
日本語のモジュールは現在メンテナンスされてない
-
-
PGroongaを使った全文検索¶ ↑
PGroonga?¶ ↑
読み方
PGroonga?¶ ↑
PGroongan (ぴ−じーるんが)
PGroongaとは?¶ ↑
PostgreSQLでn((*高速・高機能な*))全文検索を実現nする拡張
PGroongaの特徴¶ ↑
(1) ((*簡単*))に使える (2) ((*速い*)) (3) ((*全言語*))対応
使い方¶ ↑
# image # src = images/pgroonga-sql.png # relative_height = 107
使い方¶ ↑
実際に全文検索nしてみましょう
実行例:テーブル定義¶ ↑
# coderay sql CREATE TABLE entries ( title text, content text );
実行例:nインデックス定義¶ ↑
# coderay sql -- 全文検索用インデックス CREATE INDEX entries_full_text_search ON entries --「USING pgroonga」=「PGroongaを使う」 USING pgroonga (title, content);
実行例:データ挿入¶ ↑
# coderay sql -- 普通に挿入するだけでよい INSERT INTO entries VALUES ('PGroongaで高速全文検索!', '高速に全文検索したいですね!');
実行例:全文検索¶ ↑
# coderay sql SELECT title FROM entries WHERE -- &@~で全文検索 -- 「検索」と「高速」をAND検索 title &@~ '検索 高速' OR content &@~ '検索 高速';
実行例:LIKE¶ ↑
# coderay sql SELECT title FROM entries WHERE -- LIKEでもインデックスが効く --=アプリを書き換えずに高速化可能 -- ただし&@~より性能が落ちる title LIKE '%検索%' OR content LIKE '%検索%';
使い方¶ ↑
((*簡単*))ですね!
速度¶ ↑
((*安定*))して速い
ベンチマーク¶ ↑
青空文庫の書籍一覧¶ ↑
# RT delimiter = [|] 件数 | LIKE\n速度[ms] | PGroonga\n速度[ms] 11,818件 | 1.916 | 0.290
日本全国の住所¶ ↑
# RT delimiter = [|] 件数 | LIKE\n速度[ms] | PGroonga\n速度[ms] 149,724件 | 17.277 | 0.850
Wikipedia日本語版のタイトル¶ ↑
# RT delimiter = [|] 件数 | LIKE\n速度[ms] | PGroonga\n速度[ms] 3,677,375件 | 128.776 | 0.371
ベンチマークのデータ¶ ↑
-
使用したSQLは以下を参照
ベンチマークのデータ¶ ↑
-
追試用スクリプト
機能¶ ↑
-
全文検索に必要そうな機能はn一通り揃っている
-
同義語検索
-
類似文書検索
-
読みがな検索
-
入力補完 etc..
-
機能¶ ↑
-
全文検索に必要そうな機能はn一通り揃っている
-
同義語検索
-
類似文書検索
-
((*読みがな検索*))
-
入力補完 etc..
-
読みがな検索¶ ↑
「やきにく」nってどう書きますか?
読みがな検索¶ ↑
-
やきにく
-
焼き肉
-
焼肉
-
やき肉
-
ヤキニク
読みがな検索¶ ↑
当然ですがどれも「やきにく」と読みます
読みがな検索¶ ↑
-
読みが同じなので、以下は全部同じものとして扱えます
-
やきにく
-
焼き肉
-
焼肉
-
やき肉
-
ヤキニク
-
読みがな検索¶ ↑
例えばn「やきにく」で検索すると
読みがな検索¶ ↑
-
「やきにく」((Hit!))
-
「焼き肉」((Hit!))
-
「焼肉」((Hit!))
-
「やき肉」((Hit!))
-
「ヤキニク」((Hit!))
読みがな検索¶ ↑
異体字
読みがな検索¶ ↑
「広」と「廣」
読みがな検索¶ ↑
例えば人名のn検索
読みがな検索¶ ↑
検索キーワード「広瀬」で
* 「広瀬」((*Hit*)) * 「廣瀬」((*Hit*))
となってほしい
読みがな検索¶ ↑
通常の検索n 検索キーワード「広瀬」で
* 「広瀬」のみ((*Hit*))
読みがな検索¶ ↑
読みがな検索ならn 検索キーワード「広瀬」で
* 「広瀬」((*Hit*)) * 「廣瀬」((*Hit*))
読みがな検索¶ ↑
両方ヒット!
読みがな検索¶ ↑
「広瀬」もn「廣瀬」もn読みが同じ
他にも¶ ↑
-
それっぽい順でソート
-
キーワードハイライト
-
キーワードの周辺テキスト表示
他にも¶ ↑
-
電話番号検索
-
090-1234-5678 と 090 1234 5678、(090)1234-5678 等
-
-
fuzzy検索
-
typo対策
-
テクノロジーとテノクロジー
-
-
まとめ¶ ↑
PGroongaでn((*高速高機能*))なn日本語全文検索が実現できます!
より詳しく知りたい人¶ ↑
参考¶ ↑
-
PGroonga自体の解説
参考¶ ↑
-
PHPのマニュアル検索
-
((<URL:www.slideshare.net/kou/phpconference2017>))
-
-
Redmineのチケットを検索
-
((<URL:www.slideshare.net/kou/redminetokyo12>))
-
参考¶ ↑
-
AWSでPGroongaを使う