Mroonga・PGroongaを使ったn全文検索システムの実装方法¶ ↑
: author
須藤功平
: institution
株式会社クリアコード
: content-source
MySQL・PostgreSQL上で動かす全文検索エンジン「Groonga」セミナー
: date
2017-08-01
: allotted-time
105m
: theme
.
全文検索システムn対象¶ ↑
((‘tag:center’)) ((‘tag:large’)) ((‘tag:margin-bottom * 2’)) 大量のテキスト
* 例:Wikiのデータ * 例:オフィス文書のテキスト * 例:商品説明・口コミ
全文検索システムn目的¶ ↑
* 必要な情報を * 必要なときに * 活用
必要な情報を活用¶ ↑
* × * 探している情報が見つからない * ○ * 探している情報が見つかる * ◎ * 意識していなかったけど\n ((*実は欲しかった*))情報も見つかる!
必要なときに活用¶ ↑
* × * なかなか見つからない * ○ * すぐに見つかる * ◎ * すでに見つかっていた * 例:レコメンデーション
実装方法n選択肢¶ ↑
* 全文検索サーバーを使う * RDBMSを使う * MySQL・MariaDB・PostgreSQLを使う
全文検索サーバー案nメリット¶ ↑
* 必要な機能が揃っている * +αの機能もある * 速い
全文検索サーバー案nデメリット¶ ↑
* 実装コスト大 * それぞれ独自の使い方だから * マスターデータの同期はどうする? * メンテナンスコスト大 * それぞれ独自の仕組みだから
RDBMS案nメリット¶ ↑
* 実装コスト小 * 新しく覚えることが少ない * データの一元管理 * メンテナンスコスト小 * 既存の運用ノウハウを使える
RDBMS案nデメリット¶ ↑
* 組込機能では機能不足 * SQLの表現力不足 * 1クエリーで実現できない機能アリ * ↑は性能を出しにくい
実現方法n第3の選択肢¶ ↑
* RDBMS経由(SQL)で\n 全文検索エンジンを使う
メリット¶ ↑
* 高速で豊富な機能 * 実装コスト小 * メンテナンスコスト小
デメリット¶ ↑
* RDBMSに拡張機能が必要 * DBaaSで使えない
オススメの選択肢n全文検索の知識ナシ¶ ↑
* まだ単純な機能で十分 * データ少:RDBMS単独でLIKE\n (('note:(数十万件とか)')) * データ中:RDBMS組込全文検索機能 * いまどきの全文検索機能が必要 * RDBMS経由で全文検索エンジン
オススメの選択肢n全文検索の知識アリ¶ ↑
* カリカリにチューニングしたい * RDBMSと全文検索サーバーを併用 * それ以外 * RDBMS経由で全文検索エンジン
説明する選択肢¶ ↑
RDBMS経由でn 全文検索n エンジン
全文検索エンジンnGroonga(ぐるんが)¶ ↑
* 組込可能な全文検索エンジン * MySQL・MariaDBに組込→Mroonga * PostgreSQLに組込→PGoonga * 全文検索サーバーとして\n 単独でも使用可能 * RDBMSと全文検索サーバーを併用\n もできる
Groongaの得意なこと¶ ↑
* データの追加・更新 * 新鮮な情報をすぐに検索可能に! * 更新中も検索性能を落とさない! * 日本語 * 開発者が日本人 * 便利機能が組み込み
Mroonga(むるんが)¶ ↑
* MySQLのストレージエンジン * InnoDB・MyISAMなどと同じレイヤー * 使用方法 * (({CREATE TABLE (...) ENGINE=Mroonga}))
スライドプロパティ¶ ↑
: groonga-product
mroonga
MySQL組込の全文検索機能¶ ↑
* MySQL:5.7から使える * InnoDB+日本語対応パーサー * MariaDB:10.0.15から使える * Mroongaをバンドル
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索機能:基本¶ ↑
# RT , InnoDB, Mroonga AND/OR/NOT対応,○,○ ハイライト,×,○ 周辺テキスト表示,×,○
スライドプロパティ¶ ↑
: groonga-product
mroonga
ハイライトn周辺テキスト表示¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索機能:高度な機能¶ ↑
# RT , InnoDB, Mroonga 入力補完,×,○ 類似文書検索,○,○ クエリー展開,○,○
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索性能の違いn計測データ¶ ↑
* 対象:Wikipedia日本語版 * レコード数:約185万件 * データサイズ:約7GB * メモリー4GB・SSD250GB(('note:(ConoHa)'))
スライドプロパティ¶ ↑
: groonga-product
mroonga
検索性能1¶ ↑
((‘tag:center’)) キーワード:テレビアニメn ((‘note:(ヒット数:約2万3千件)’))
# RT delimiter = [|] InnoDB ngram | 3m2s InnoDB MeCab | 6m20s Mroonga:((*1*)) | 0.11s
スライドプロパティ¶ ↑
: groonga-product
mroonga
検索性能2¶ ↑
((‘tag:center’)) キーワード:データベースn ((‘note:(ヒット数:約1万7千件)’))
# RT delimiter = [|] InnoDB ngram | 36s InnoDB MeCab:((*1*)) | 0.03s Mroonga:((*2*)) | 0.09s
スライドプロパティ¶ ↑
: groonga-product
mroonga
検索性能3¶ ↑
((‘tag:center’)) キーワード:PostgreSQL OR MySQLn ((‘note:(ヒット数:約400件)’))
# RT delimiter = [|] InnoDB ngram | N/A(Error) InnoDB MeCab:((*1*)) | 0.005s Mroonga:((*2*)) | 0.028s
スライドプロパティ¶ ↑
: groonga-product
mroonga
検索性能4¶ ↑
((‘tag:center’)) キーワード:日本n ((‘note:(ヒット数:約63万件)’))
# RT delimiter = [|] InnoDB ngram | 1.3s InnoDB MeCab | 1.3s Mroonga:((*1*)) | 0.21s
スライドプロパティ¶ ↑
: groonga-product
mroonga
検索性能まとめ¶ ↑
* Mroonga:安定して速い * ((*SQLで使えて機能豊富で速い!*)) * InnoDB FTS MeCab * ハマれば速い * InnoDB FTS ngram * 安定して遅い
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索システムの実装nMroonga¶ ↑
* 全文検索 * キーワードハイライト * 周辺テキスト表示 * 入力補完 * 関連文書の表示
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
mroonga
テーブル定義¶ ↑
# coderay sql CREATE TABLE entries ( title text, content text, -- 全文検索用インデックス -- よくわからないならデフォルトのまま使うこと! FULLTEXT INDEX (title, content) ) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
スライドプロパティ¶ ↑
: groonga-product
mroonga
データ挿入¶ ↑
# coderay sql -- 普通に挿入するだけでよい INSERT INTO entries VALUES ('タイトル', '高速に全文検索したいですね!');
スライドプロパティ¶ ↑
: groonga-product
mroonga
全文検索¶ ↑
# coderay sql SELECT title FROM entries WHERE -- MATCH AGAINSTで全文検索 MATCH (title, content) -- デフォルトORがMySQLの仕様 -- 「検索」または「高速」を含むとマッチ AGAINST ('検索 高速' IN BOOLEAN MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
AND全文検索¶ ↑
# coderay sql MATCH (title, content) -- 各キーワードの前に「+」をつけるとAND -- 「検索」かつ「高速」を含むとマッチ AGAINST ('+検索 +高速' IN BOOLEAN MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
使いやすいAND全文検索¶ ↑
# coderay sql MATCH (title, content) -- 最初に「*D+」をつけるとデフォルトAND -- Mroonga独自機能 -- 「検索」かつ「高速」を含むとマッチ AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
スコアー¶ ↑
# coderay sql SELECT title, -- ここのMATCH AGAINSTはスコアーを返す MATCH (title, content) AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE) AS score FROM entries WHERE -- ... -- スコアーが高い順にソート ORDER BY score DESC LIMIT 10;
スライドプロパティ¶ ↑
: groonga-product
mroonga
ハイライト¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
mroonga
ハイライト¶ ↑
# coderay sql SELECT mroonga_highlight_html( title, '*D+ 検索 高速' AS query) -- クエリーからハイライト対象のキーワードを抽出 FROM entries WHERE MATCH (title, content) AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
ハイライト結果例¶ ↑
# coderay html <Groonga>で高速全文検索! ↓ <Groonga>で ← タグをエスケープ <span class="keyword">高速</span> 全文 ↑↓キーワードはclass付け <span class="keyword">検索</span>!
スライドプロパティ¶ ↑
: groonga-product
mroonga
周辺テキスト¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
mroonga
周辺テキスト¶ ↑
# coderay sql SELECT mroonga_snippet_html( content, '*D+ 検索 高速' AS query) -- クエリーから対象のキーワードを抽出 FROM entries WHERE MATCH (title, content) AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
周辺テキスト結果例¶ ↑
# coderay html ...<Groonga>で高速全文検索!... ↓ <div class="snippet"> ←1つ目 ga>で ←タグをエスケープ <span class="keyword">高速</span> 全文 ↑↓キーワードはclass付け <span class="keyword">検索/span>! </div> <div class="snippet">...</div> ←2つ目
スライドプロパティ¶ ↑
: groonga-product
mroonga
類似文書検索¶ ↑
* 検索クエリーは文書そのもの * キーワードではない * 関連エントリーの提示に使える * メタデータがあるなら組み合わせる\n →精度向上 * メタデータ:タグ・行動履歴など
スライドプロパティ¶ ↑
: groonga-product
mroonga
類似文書検索nインデックス定義¶ ↑
# coderay sql CREATE TABLE entries ( -- ... FULLTEXT INDEX (content) -- TokenMecabを使わないと精度がでない -- 必要なときだけカスタマイズ! COMMENT 'tokenizer "TokenMecab"' ) -- ...
スライドプロパティ¶ ↑
: groonga-product
mroonga
類似文書検索n検索方法¶ ↑
# coderay sql SELECT title FROM entries WHERE MATCH (content) ↓ 既存文書の内容をそのまま指定 AGAINST ('...Groongaで高速全文検索!...' IN NATURAL LANGUAGE MODE);
スライドプロパティ¶ ↑
: groonga-product
mroonga
類似文書検索n結果例¶ ↑
クエリー: ...Groongaで高速全文検索!... ヒット例: ...Mroongaで高速全文検索!...
スライドプロパティ¶ ↑
: groonga-product
mroonga
照合順序:COLLATION¶ ↑
* 文字の並び順の規則 * 文字が同一かどうかの判定にも利用 * 適切な日本語規則なし * いわゆる🍣=🍺問題
((‘note:MySQL 8では適切な日本語規則が追加される’))
スライドプロパティ¶ ↑
: groonga-product
mroonga
Mroongaの照合順序¶ ↑
* MySQL互換のもの * MySQL互換を微調整したもの * 日本語でもいい感じ * Groonga提供のもの * 日本語でもいい感じ
スライドプロパティ¶ ↑
: groonga-product
mroonga
微調整した照合順序¶ ↑
# coderay sql FULLTEXT INDEX (content) COMMENT 'normalizer "${ノーマライザー名}"' ノーマライザー名: NormalizerMySQLUnicode520CI ExceptKanaCI KanaWithVoicedSoundMark
スライドプロパティ¶ ↑
: groonga-product
mroonga
PGroongan(ぴーじーるんが)¶ ↑
* PostgreSQLのインデックス * B-tree・GINなどと同じレイヤー * 使用方法 * (({CREATE INDEX ...}))\n (({USING PGroonga ...}))
スライドプロパティ¶ ↑
: groonga-product
pgroonga
PostgreSQLの全文検索機能¶ ↑
* textsearch(組込) * 言語依存 * 日本語対応はメンテされていない * pg_trgm(同梱) * 言語非依存:が、ほぼ日本語非対応 * pg_bigm(サードパーティー) * 言語非依存:日本語対応
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索機能:基本¶ ↑
# RT , pg_bigm, PGroonga AND/OR/NOT対応,△※1,○ ハイライト,△※2,○ 周辺テキスト表示,△※2,○
((‘note:※1 SQLでAND/OR/NOTを組み合わせると実現可能’))
((‘note:※2 PostgreSQLが提供する関数で実現可能。ただし、結果をHTMLで出力する用途では使えない。’))
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索機能:高度な機能¶ ↑
# RT , pg_bigm, PGroonga 入力補完,×,○ 類似文書検索,△※,○ クエリー展開,×,○
((‘note:※ 類似文書検索と言うよりはあいまい検索。’))
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索性能の違いn計測データ¶ ↑
* 対象:Wikipedia日本語版 * レコード数:約90万件 * データサイズ:約6GB * メモリー32GB・SSD500GB
スライドプロパティ¶ ↑
: groonga-product
pgroonga
検索性能1¶ ↑
((‘tag:center’)) キーワード:テレビアニメn ((‘note:(ヒット数:約2万件)’))
# RT delimiter = [|] pg_bigm | 2.800s PGroonga:((*1*)) | 0.065s Groonga(参考) | 0.038s
スライドプロパティ¶ ↑
: groonga-product
pgroonga
検索性能2¶ ↑
((‘tag:center’)) キーワード:データベースn ((‘note:(ヒット数:約1万5千件)’))
# RT delimiter = [|] pg_bigm | 1.300s PGroonga:((*1*)) | 0.049s Groonga(参考) | 0.031s
スライドプロパティ¶ ↑
: groonga-product
pgroonga
検索性能3¶ ↑
((‘tag:center’)) キーワード:PostgreSQL OR MySQLn ((‘note:(ヒット数:約300件)’))
# RT delimiter = [|] pg_bigm | 0.049s PGroonga:((*1*)) | 0.002s Groonga(参考) | 0.001s
スライドプロパティ¶ ↑
: groonga-product
pgroonga
検索性能4¶ ↑
((‘tag:center’)) キーワード:日本n ((‘note:(ヒット数:約53万件)’))
# RT delimiter = [|] pg_bigm:((*1*)) | 0.479s PGroonga | 0.563s Groonga(参考) | 0.059s
スライドプロパティ¶ ↑
: groonga-product
pgroonga
検索性能まとめ¶ ↑
* PGroonga:安定して速い * ((*SQLで使えて機能豊富で速い!*)) * pg_bigm * ヒット数が少なければ速い * キーワードが2文字以下なら速い
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索システムの実装nPGroonga¶ ↑
* 全文検索 * キーワードハイライト * 周辺テキスト表示 * 入力補完 * 関連文書の表示
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
pgroonga
テーブル定義¶ ↑
# coderay sql CREATE TABLE entries ( -- プライマリーキーを用意する -- スコアーでソートするために必要 id integer PRIMARY KEY, title text, content text );
スライドプロパティ¶ ↑
: groonga-product
pgroonga
インデックス定義¶ ↑
# coderay sql -- 全文検索用インデックス -- よくわからないなら -- デフォルトのまま使うこと! CREATE INDEX entries_full_text_search ON entries --「USING PGroonga」=「PGroongaを使う」 USING PGroonga (id, title, content);
スライドプロパティ¶ ↑
: groonga-product
pgroonga
データ挿入¶ ↑
# coderay sql -- 普通に挿入するだけでよい INSERT INTO entries VALUES (1, 'Groongaで高速全文検索!', '高速に全文検索したいですね!');
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索¶ ↑
# coderay sql SELECT title FROM entries WHERE -- &@~で全文検索 -- 「検索」と「高速」をAND検索 title &@~ '検索 高速' OR content &@~ '検索 高速';
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索:LIKE¶ ↑
# coderay sql SELECT title FROM entries WHERE -- LIKEでもインデックスが効く --=アプリを書き換えずに高速化可能 -- ただし&@~より性能が落ちる title LIKE '%検索%' OR content LIKE '%検索%';
スライドプロパティ¶ ↑
: groonga-product
pgroonga
スコアー¶ ↑
# coderay sql SELECT title, -- pgroonga.score(テーブル名)で -- スコアーを取得 pgroonga.score(entries) AS score FROM entries WHERE -- ... -- スコアーが高い順にソート ORDER BY score DESC LIMIT 10;
スライドプロパティ¶ ↑
: groonga-product
pgroonga
ハイライト¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
pgroonga
ハイライト¶ ↑
# coderay sql SELECT pgroonga.highlight_html( title, -- クエリーから対象キーワードを抽出 pgroonga.query_extract_keywords('検索 高速')) FROM entries WHERE title &@~ '検索 高速' OR content &@~ '検索 高速';
スライドプロパティ¶ ↑
: groonga-product
pgroonga
ハイライト結果例¶ ↑
# coderay html <Groonga>で高速全文検索! ↓ <Groonga>で ← タグをエスケープ <span class="keyword">高速</span> 全文 ↑↓キーワードはclass付け <span class="keyword">検索</span>!
スライドプロパティ¶ ↑
: groonga-product
pgroonga
周辺テキスト¶ ↑
# image # src = images/php-document-search-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
pgroonga
周辺テキスト¶ ↑
# coderay sql SELECT pgroonga.snippet_html( content, -- クエリーから対象キーワードを抽出 pgroonga.query_extract_keywords('検索 高速')) FROM entries WHERE title &@~ '検索 高速' OR content &@~ '検索 高速';
スライドプロパティ¶ ↑
: groonga-product
pgroonga
周辺テキスト結果例¶ ↑
# coderay html ...<Groonga>で高速全文検索!... ↓ ARRAY[ ↓ 1つ目 'ga>で ←タグをエスケープ <span class="keyword">高速</span> 全文 ↑↓キーワードはclass付け <span class="keyword">検索/span>!', '...' ← 2つ目 ]
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完¶ ↑
# image # src = images/php-document-search.png # relative_height = 100
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n実装方法¶ ↑
* 以下の検索のOR * 前方一致検索 * ヨミガナでの前方一致検索 * 緩い全文検索 * 表示文字列でソートして提示
((‘tag:xx-small’)) pgroonga.github.io/ja/how-to/auto-complete.html
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完nテーブル定義¶ ↑
# coderay sql CREATE TABLE terms ( -- 補完候補 term text, -- この候補のヨミガナ(N個可) readings text[] );
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完nデータ例¶ ↑
# coderay sql INSERT INTO terms VALUES ( '牛乳', -- 補完候補 ARRAY[ -- ヨミガナはカタカナで指定する 'ギュウニュウ', -- 「ミルク」でも補完できるようになる 'ミルク' ] );
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完nデータ管理のポイント¶ ↑
* 普通のテーブルなので管理が楽 * 追加・削除・更新が楽 * ダンプ・リストアもいつも通り * レプリケーションもいつも通り
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n前方一致用インデックス¶ ↑
# coderay sql CREATE INDEX prefix_search ON terms USING PGroonga -- ...text_term_search... (term pgroonga.text_term_search_ops_v2, -- ...text_array_term_search... readings pgroonga.text_array_term_search_ops_v2);
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n緩い全文検索用¶ ↑
# coderay sql CREATE INDEX loose_search ON terms USING PGroonga -- ...text_full_text_search... (term pgroonga.text_full_text_search_ops_v2) -- 緩い全文検索用トークナイザー WITH (tokenizer='TokenBigramSplitSymbolAlphaDigit');
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索方法¶ ↑
# coderay sql SELECT term FROM terms -- 前方一致検索 WHERE term &^ '${入力}' OR -- ローマ字で前方一致検索 readings &^~ '${入力}' OR -- 緩い全文検索 term &@ '${入力}' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索例:漢字1¶ ↑
# coderay sql -- ユーザーが「牛」を入力した場合 SELECT term FROM terms -- 前方一致検索(ヒット) WHERE term &^ '牛' OR -- ヨミガナで前方一致検索 readings &^~ '牛' OR -- 緩い全文検索(ヒット) term &@ '牛' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索例:漢字2¶ ↑
# coderay sql -- ユーザーが「乳」を入力した場合 SELECT term FROM terms -- 前方一致検索 WHERE term &^ '乳' OR -- ヨミガナで前方一致検索 readings &^~ '乳' OR -- 緩い全文検索(ヒット) term &@ '乳' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索例:カタカナ¶ ↑
# coderay sql -- ユーザーが「ギュウ」を入力した場合 SELECT term FROM terms -- 前方一致検索 WHERE term &^ 'ギュウ' OR -- ヨミガナで前方一致検索(ヒット) readings &^~ 'ギュウ' OR -- 緩い全文検索 term &@ 'ギュウ' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索例:ひらがな¶ ↑
# coderay sql -- ユーザーが「ぎゅう」を入力した場合 SELECT term FROM terms -- 前方一致検索 WHERE term &^ 'ぎゅう' OR -- ヨミガナで前方一致検索(ヒット) readings &^~ 'ぎゅう' OR -- 緩い全文検索 term &@ 'ぎゅう' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
入力補完n検索例:ローマ字¶ ↑
# coderay sql -- ユーザーが「gyu」を入力した場合 SELECT term FROM terms -- 前方一致検索 WHERE term &^ 'gyu' OR -- ヨミガナで前方一致検索(ヒット) readings &^~ 'gyu' OR -- 緩い全文検索 term &@ 'gyu' ORDER BY term LIMIT 10; -- ソート
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開¶ ↑
* 同義語 * 同じ意味だが表記が異なる語 * 例:「刺身」と「お造り」 * どの表記でもヒットして欲しい * 同義語展開→同義語すべてでOR検索
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開n実装方法¶ ↑
* 同義語管理テーブルを作成 * クエリー内の同義語を展開 * 展開後のクエリーで検索
((‘tag:xx-small’)) pgroonga.github.io/ja/reference/functions/pgroonga-query-expand.html
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開nテーブル定義¶ ↑
# coderay sql CREATE TABLE synonyms ( -- 展開対象の語 term text, -- 同義語のリスト -- term自身も含める -- 含めない場合はtermが検索禁止語になる terms text[] );
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開nデータ例¶ ↑
# coderay sql INSERT INTO synonyms VALUES ('刺身', -- 「刺身」を展開 ARRAY['刺身', 'お造り']), ('お造り', -- 「お造り」を展開 ARRAY['お造り', '刺身']);
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開nデータ管理のポイント¶ ↑
* 普通のテーブルなので管理が楽 * 追加・削除・更新が楽 * ダンプ・リストアもいつも通り * レプリケーションもいつも通り
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開nインデックス定義¶ ↑
# coderay sql CREATE INDEX synonym_search ON synonyms USING PGroonga -- ...text_term_search... -- termで完全一致検索をするため (term pgroonga.text_term_search_ops_v2);
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開n確認方法¶ ↑
# coderay sql SELECT pgroonga.query_expand( 'synonyms', -- テーブル名 'term', -- 展開対象のカラム名 'terms', -- 対応する同義語配列のカラム名 '刺身' -- クエリー ); -- '((刺身) OR (お造り))'
スライドプロパティ¶ ↑
: groonga-product
pgroonga
同義語展開n検索方法¶ ↑
# coderay sql SELECT title FROM entries WHERE -- title &@~ '和食 OR ((刺身) OR (お造り))'になる title &@~ pgroonga.query_expand('synonyms', 'term', 'terms', '和食 OR 刺身');
スライドプロパティ¶ ↑
: groonga-product
pgroonga
類似文書検索¶ ↑
* 検索クエリーは文書そのもの * キーワードではない * 関連エントリーの提示に使える * メタデータがあるなら組み合わせる\n →精度向上 * メタデータ:タグ・行動履歴など
スライドプロパティ¶ ↑
: groonga-product
pgroonga
類似文書検索nインデックス定義¶ ↑
# coderay sql CREATE INDEX entries_similar_search ON entries USING PGroonga ( id, -- pg...v2の指定がポイント content pgroonga.text_full_text_search_ops_v2 -- TokenMecabを使うと精度向上 ) WITH (tokenizer='TokenMecab');
スライドプロパティ¶ ↑
: groonga-product
pgroonga
類似文書検索n検索方法¶ ↑
# coderay sql SELECT title FROM entries WHERE -- &~?で類似文書検索 -- 既存文書の内容をそのまま指定 content &~? '...Groongaで高速全文検索!...';
スライドプロパティ¶ ↑
: groonga-product
pgroonga
類似文書検索n結果例¶ ↑
クエリー: ...Groongaで高速全文検索!... ヒット例: ...PGroongaで高速全文検索!...
スライドプロパティ¶ ↑
: groonga-product
pgroonga
全文検索システムの実装nまとめ¶ ↑
* 全文検索 * キーワードハイライト * 周辺テキスト表示 * 入力補完 * 関連文書の表示
全文検索システムの実装n次の一歩¶ ↑
* 構造化データ対応 * オフィス文書・HTMLなど * 対応に必要な処理 * テキスト抽出 * メタデータ抽出(('note:(例:タイトル・更新日時)')) * スクリーンショット作成(('note:(なおよい)'))
抽出ツール¶ ↑
* Apache Tika * Apache Luceneのサブプロジェクト * 対応フォーマット数が多い * ChupaText * Groongaのサブプロジェクト * スクリーンショット作成対応
ChupaText¶ ↑
* 対応フォーマット * Word/Excel/PowerPoint * ODT/ODS/ODP(('note:(OpenDocument)')) * PDF/HTML/XML/CSV/... * インターフェイス * HTTPとコマンドライン
ChupaText:インストール¶ ↑
* DockerかVagrantを使うのが楽 * (('tag:xx-small')) https://github.com/ranguba/chupa-text-docker * (('tag:xx-small')) https://github.com/ranguba/chupa-text-vagrant
ChupaText:Docker¶ ↑
# coderay console % GITHUB=https://github.com % git clone \ ${GITHUB}/ranguba/chupa-text-docker.git % cd chupa-text-docker % docker-compose up --build
ChupaText:使い方¶ ↑
# coderay console % curl \ --form data=@XXX.pdf \ http://localhost:20080/extraction.json
ChupaText:結果例¶ ↑
# coderay json { "mime-type": "application/pdf", # 元データのMIMEタイプ "size": 147159, # メタデータ ..., "texts": [ # 抽出されたテキスト(N個) { "mime-type": "text/plain", # 抽出後のMIMEタイプ ..., "creator": "Adobe Illustrator CS3", # メタデータ "body": "This is sample PDF. ...", # 抽出したテキスト "screenshot": { "mime-type": "image/png", # スクリーンショットのMIMEタイプ "data": "iVBORw...", # Base64にした画像データ "encoding": "base64" # Base64であることを明記 } } ] }
ChupaText:Web UI¶ ↑
# image # src = images/chupa-text-web-ui-form.png # relative_height = 100
ChupaText:Web UI抽出例¶ ↑
# image # src = images/chupa-text-web-ui-extract-metadata.png # relative_height = 100
ChupaText:Web UI抽出例¶ ↑
# image # src = images/chupa-text-web-ui-extract-text-and-screenshot.png # relative_height = 100
ChupaText:Vagrant¶ ↑
# coderay console % GITHUB=https://github.com % git clone \ ${GITHUB}/ranguba/chupa-text-vagrant.git % cd chupa-text-vagrant % vagrant up
((‘tag:center’)) 使い方はDocker版と同じ
ChupaText:活用例¶ ↑
* 抽出したテキスト * Mroonga・PGroongaへ挿入 * 抽出したメタデータ * Mroonga・PGroongaへ挿入 * 絞り込みに活用 * 作成したスクリーンショット * 検索結果表示時に掲載
まとめ¶ ↑
* RDBMS経由で全文検索エンジン * 採用の判断材料を提供 * 全文検索システム実装例を紹介 * Mroonga・PGroonga両方 * 構造化データの対応方法を紹介 * ChupaText
扱わなかった話題¶ ↑
* 運用について * 障害対策・レプリケーション * チューニング * Groongaの機能を直接使う方法
((‘tag:center’)) 今後のセミナーの話題にするにはn 実例ベースの方がやりやすいのでn あなたのケースを教えてください
サポートサービス紹介¶ ↑
* 導入支援(('note:(設計支援・性能検証・移行支援・…)')) * 開発支援\n (('note:(サンプルコード提供・問い合わせ対応・…)')) * 運用支援(('note:(障害対応・チューニング支援・…)'))
問い合わせ先:
((‘tag:x-small’)) www.clear-code.com/contact/?type=groonga