Rabbit Slide Show

MariaDBとMroongaで作る全言語対応超高速全文検索システム

2018-01-30

Description

MariaDBには超高速な全文検索を実現するMroongaストレージエンジンがバンドルされていることを知っていますか?Mroongaを使うと日本語だけでなくアジア圏の言語も含むすべての言語をサポートした超高速な全文検索システムを簡単に作ることができます。どれだけ簡単に作ることができるか紹介します。

Text

Page: 1

MariaDBとMroongaで作る
全言語対応
超高速全文検索システム
須藤功平
クリアコード
第一回 JPMUG DB勉強会
2018-01-30
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 2

全文検索システム
対象
大量のテキスト
例:Wikiのデータ
例:オフィス文書のテキスト
例:商品説明・口コミ
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 3

全文検索システム
目的
必要な情報を
必要なときに
活用
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 4

必要な情報を活用
×
探している情報が見つからない
○
探している情報が見つかる
◎
意識していなかったけど
実は欲しかった情報も見つかる!
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 5

必要なときに活用
×
なかなか見つからない
○
すぐに見つかる
◎
すでに見つかっていた
例:レコメンデーション
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 6

実装方法
選択肢
全文検索サーバーを使う
MariaDBでLIKEを使う
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 7

全文検索サーバー案
メリット
必要な機能が揃っている
+αの機能もある
速い
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 8

全文検索サーバー案
デメリット
実装コスト大
それぞれ独自の使い方だから
マスターデータの同期はどうする?
メンテナンスコスト大
それぞれ独自の仕組みだから
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 9

MariaDBでLIKE案
メリット
実装コスト小
新しく覚えることが少ない
データの一元管理
メンテナンスコスト小
既存の運用ノウハウを使える
データ少なら実用的な速度
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 10

MariaDBでLIKE案
デメリット
機能不足
それっぽい順のソート不可
全文検索ではソート順が重要
ユーザーは先頭n件しか見ない
SQLの表現力不足
nクエリーで実現すると性能に影響
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 11

実現方法
第3の選択肢
MariaDB経由(SQL)で
全文検索エンジンを使う
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 12

メリット
高速で豊富な機能
それっぽい順のソート可
実装コスト小
メンテナンスコスト小
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 13

デメリット
MariaDBに拡張機能が必要
RDS・Azure databaseで使えない
(Azure database for MariaDBはまだリリース前)
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 14

オススメの選択肢
全文検索の知識ナシ
まだ単純な機能で十分
データ少:MariaDB単独でLIKE
(数十万件とか)
データ中以上:
MariaDB経由で全文検索エンジン
いまどきの全文検索機能が必要
MariaDB経由で全文検索エンジン
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 15

オススメの選択肢
全文検索の知識アリ
カリカリにチューニングしたい
MariaDBと全文検索サーバーを併用
それ以外
MariaDB経由で全文検索エンジン
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 16

説明する選択肢
MariaDB経由で
全文検索
エンジン
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 17

全文検索エンジン
Groonga(ぐるんが)
組込可能な全文検索エンジン
MariaDB・MySQLに組込→Mroonga
PostgreSQLに組込→PGroonga
全文検索サーバーとして
単独でも使用可能
MariaDBと全文検索サーバーを併用
もできる
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 18

Groongaの得意なこと
データの追加・更新
新鮮な情報をすぐに検索可能に!
更新中も検索性能を落とさない!
日本語
開発者が日本人
便利機能が組み込み
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 19

GroongaとUnicode
NFKCベースの正規化機能を組込
Unicode 5.1ベースで古い
2008年の仕様
Unicode 10.0(最新)対応中
正規化方式を変えるとインデックスの互換性がなくなる
(=要インデックス再構築)のでデフォルトは変えない
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 20

Mroonga(むるんが)
MariaDBのストレージエンジン
InnoDB・MyISAMなどと同じレイヤー
MariaDB 10.0.15から標準バンドル
使用方法
CREATE TABLE (...)
ENGINE=Mroonga
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 21

照合順序:COLLATION
文字の並び順の規則
文字が同一かどうかの判定にも利用
適切な日本語規則なし
いわゆる
=
問題
MySQL 8では適切な日本語規則が追加される
utf8mb4_ja_0900_as_csなど
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 22

Mroongaの照合順序
MariaDB互換のもの
utf8mb4_ja_0900_*互換は対応予定
MariaDB互換を微調整したもの
日本語でもいい感じ
Groonga提供のもの
NFKCベースのもの
日本語でもいい感じ
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 23

Mroongaで照合順序
MariaDB互換がよい!
互換正規化処理を使用:デフォルト
MariaDB互換は気にしないから
いい感じに!
Groonga提供のものを使用
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 24

全文検索性能
計測データ
対象:Wikipedia日本語版
レコード数:約185万件
データサイズ:約7GB
メモリー4GB・SSD250GB (ConoHa)
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 25

検索性能1
キーワード:テレビアニメ
(ヒット数:約2万3千件)
InnoDB ngram
InnoDB MeCab
Mroonga:1
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
3m2s
6m20s
0.11s
Powered by Rabbit 2.2.2

Page: 26

検索性能2
キーワード:データベース
(ヒット数:約1万7千件)
InnoDB ngram
InnoDB MeCab:1
Mroonga:2
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
36s
0.03s
0.09s
Powered by Rabbit 2.2.2

Page: 27

検索性能3
キーワード:PostgreSQL OR MySQL
(ヒット数:約400件)
InnoDB ngram
N/A(Error)
InnoDB MeCab:1
0.005s
Mroonga:2
0.028s
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 28

検索性能4
キーワード:日本
(ヒット数:約63万件)
InnoDB ngram
InnoDB MeCab
Mroonga:1
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
1.3s
1.3s
0.21s
Powered by Rabbit 2.2.2

Page: 29

全文検索性能まとめ
Mroonga:安定して速い
SQLで使えて機能豊富で速い!
InnoDB FTS MeCab
ハマれば速い
InnoDB FTS ngram
安定して遅い
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 30

普通の検索も速い
カラムストアを活かした最適化
ポイント1:余計なI/Oを減らす
ポイント2:I/Oを局所化
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 31

カラムストア
カラム
a b c
Mroonga
1 値 値 値
カラム
a b c
InnoDB他
2 値 値 値
3 値 値 値
1 値 値 値
2 値 値 値
3 値 値 値
カラムごと 値の管理単位 行ごと
カラム 高速なアクセス単位 行
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 32

必要なカラムのみアクセス
-- aのみにアクセス
SELECT a
FROM table
-- cのみにアクセス
WHERE c = XXX;
-- bにはアクセスしない
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 33

減ったI/O
カラム
a b c
アクセスしない
2 値 値 値
カラム
a b c
InnoDB他
1 値 値 値
Mroonga
3 値 値 値
1 値 値 値
2 値 値 値
3 値 値 値
カラムごと 値の管理単位 行ごと
カラム 高速なアクセス単位 行
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 34

行カウント
-- カラムの値は必要ない
SELECT COUNT(*)
FROM table
-- cの全文検索インデックスにだけアクセス
WHERE MATCH(c)
AGAINST('+keyword' IN BOOLEAN MODE);
-- a, b, cはアクセスしない
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 35

減ったI/O
カラム
a b c
アクセスしない
2 値 値 値
カラム
a b c
InnoDB他
1 値 値 値
Mroonga
3 値 値 値
1 値 値 値
2 値 値 値
3 値 値 値
カラムごと 値の管理単位 行ごと
カラム 高速なアクセス単位 行
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 36

ORDER BY LIMIT
SELECT a
FROM table
WHERE MATCH(c)
AGAINST('+keyword' IN BOOLEAN MODE)
-- MariaDBではなくMroongaがORDER BY LIMITを処理
-- →Mroongaは10レコードだけMariaDBに返す
-- マッチしたレコードすべては返さない
ORDER BY a LIMIT 10;
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 37

ORDER BY LIMITの最適化
Mroongaが検索
カラム毎の処理でI/Oを局所化
(索引非使用時)
Mroongaがソート
カラム毎の処理でI/Oを局所化
MroongaがOFFSET/LIMITを処理
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 38

カラム毎の処理は速い
カラム
a b c
Mroonga
1 値 値 値
2 値 値 値
カラム
a b c
InnoDB他
3 値 値 値
1 値 値 値
2 値 値 値
3 値 値 値
カラムごと 値の管理単位 行ごと
カラム 高速なアクセス単位 行
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 39

condition push downの最適化
従来はMariaDBが処理していた
検索条件をストレージエンジン
が処理する仕組み
ストレージエンジンでの処理の方が
高速なら全体として高速になる
Mroonga 7.10から実験的に対応
デフォルトオフ
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 40

condition push downの効果
全文検索インデックスのみ
等価条件:シーケンシャルスキャン
全文検索:インデックススキャン
データ
シカゴの犯罪データ (651万レコード)
詳細:https://github.com/kou/rabbit-slide-kou-jpmug-db-
study-1/blob/master/memo.md
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 41

等価条件:数値1つ
26万件ヒットするケース
InnoDB
1.3s
Mroonga
1.3s
(デフォルト)
Mroonga
0.4s
(最適化ON)
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 42

等価条件:数値1つ+真偽値2つ
7000件ヒットするケース
InnoDB
1.6s
Mroonga
2.3s
(デフォルト)
Mroonga
0.4s
(最適化ON)
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 43

全文検索+等価条件
4000件ヒットするケース
InnoDB
18s
Mroonga
0.4s
(デフォルト)
Mroonga
0.4s
(最適化ON)
このパターンはデフォルトで最適化が効く
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 44

Mroongaの検索性能まとめ
最適化が効くと桁違いに速い
全文検索のときはデフォルトで効く
7.10からさらなる最適化が!
まだ実験的扱いなのでデフォルトオフ
OLAP用途にも使える
MariaDB ColumnStoreを補完する
立ち位置も可
参考:http://mroonga.org/ja/docs/reference/
server_variables.html#mroonga-condition-push-down-type
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 45

全文検索システムの実装
全文検索
キーワードハイライト
周辺テキスト表示
オートコンプリート
同義語展開
関連文書の表示
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 46

全文検索
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 47

テーブル定義
CREATE TABLE entries (
title text,
content text,
-- 全文検索用インデックス
-- よくわからないならデフォルトのまま使うこと!
FULLTEXT INDEX (title, content)
) ENGINE=Mroonga
DEFAULT CHARSET=utf8mb4;
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 48

データ挿入
-- 普通に挿入するだけでよい
INSERT INTO entries
VALUES ('タイトル',
'高速に全文検索したいですね!');
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 49

全文検索
SELECT title FROM entries
WHERE -- MATCH AGAINSTで全文検索
MATCH (title, content)
-- デフォルトORがMariaDBの仕様
-- 「検索」または「高速」を含むとマッチ
AGAINST ('検索 高速'
IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 50

AND全文検索
MATCH (title, content)
-- 各キーワードの前に「+」をつけるとAND
-- 「検索」かつ「高速」を含むとマッチ
AGAINST ('+検索 +高速'
IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 51

使いやすいAND全文検索
MATCH (title, content)
-- 最初に「*D+」をつけるとデフォルトAND
-- Mroonga独自機能
-- 「検索」かつ「高速」を含むとマッチ
AGAINST ('*D+ 検索 高速'
IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 52

それっぽい順のソート
SELECT
title,
-- ここのMATCH AGAINSTはスコアーを返す
MATCH (title, content)
AGAINST ('*D+ 検索 高速'
IN BOOLEAN MODE) AS score
FROM entries
WHERE -- ...
-- それっぽさでソート
ORDER BY score DESC LIMIT 10;
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 53

ハイライト
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 54

ハイライト
SELECT mroonga_highlight_html(
title, '*D+ 検索 高速' AS query)
-- クエリーからハイライト対象のキーワードを抽出
FROM entries
WHERE
MATCH (title, content)
AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 55

ハイライト結果例
<Groonga>で高速全文検索!
↓
&lt;Groonga&gt;で ← タグをエスケープ
<span class="keyword">高速</span>
全文 ↑↓キーワードはclass付け
<span class="keyword">検索</span>!
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 56

周辺テキスト
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 57

周辺テキスト
SELECT mroonga_snippet_html(
content, '*D+ 検索 高速' AS query)
-- クエリーから対象のキーワードを抽出
FROM entries
WHERE
MATCH (title, content)
AGAINST ('*D+ 検索 高速' IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 58

周辺テキスト結果例
...<Groonga>で高速全文検索!...
↓
<div class="snippet"> ←1つ目
ga&gt;で ←タグをエスケープ
<span class="keyword">高速</span>
全文 ↑↓キーワードはclass付け
<span class="keyword">検索/span>!
</div>
<div class="snippet">...</div> ←2つ目
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 59

オートコンプリート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 60

オートコンプリート:必要なもの
マスターテーブル
候補(例:牛乳)
候補のヨミ(カタカナ・複数可)
例1:ギュウニュウ
例2:ミルク
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 61

オートコンプリート:実装方法
以下の検索のOR
ヨミでの前方一致検索
候補を緩い全文検索
候補でソートして提示
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 62

オートコンプリート:テーブル定義
CREATE TABLE terms (
term varchar(256),
-- 補完候補
reading varchar(256),
-- ヨミガナ
PRIMARY KEY (term, reading),
FULLTEXT INDEX (term)
-- 候補全文検索用
-- 緩い全文検索用トークナイザー
COMMENT 'tokenizer "TokenBigramSplitSymbolAlpha"',
FULLTEXT INDEX (reading) -- ヨミガナ前方一致用
COMMENT 'normalizer "NormalizerAuto",
tokenizer "off"' -- トークナイザー不要
) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 63

オートコンプリート:データ例
INSERT INTO terms VALUES (
'牛乳', -- 補完候補
'ギュウニュウ' --ヨミガナはカタカナで指定
);
INSERT INTO terms VALUES (
'牛乳',
'ミルク' -- 「ミルク」でも補完できるように
);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 64

オートコンプリート
データ管理のポイント
普通のテーブルなので管理が楽
追加・削除・更新が楽
ダンプ・リストアもいつも通り
レプリケーションもいつも通り
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 65

オートコンプリート
検索方法
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape(${入力} AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索
AGAINST (CONCAT('*D+ ', mroonga_escape(${入力}))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 66

オートコンプリート
検索例:漢字1
-- ユーザーが「牛」を入力した場合
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape('牛' AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索(ヒット)
AGAINST (CONCAT('*D+ ', mroonga_escape('牛'))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 67

オートコンプリート
検索例:漢字2
-- ユーザーが「乳」を入力した場合
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape('乳' AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索(ヒット)
AGAINST (CONCAT('*D+ ', mroonga_escape('乳'))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 68

オートコンプリート
検索例:カタカナ
-- ユーザーが「ギュウ」を入力した場合
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索(ヒット)
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape('ギュウ' AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索
AGAINST (CONCAT('*D+ ', mroonga_escape('ギュウ'))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 69

オートコンプリート
検索例:ひらがな
-- ユーザーが「ぎゅう」を入力した場合
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索(ヒット)
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape('ぎゅう' AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索
AGAINST (CONCAT('*D+ ', mroonga_escape('ぎゅう'))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 70

オートコンプリート
検索例:ローマ字
-- ユーザーが「gyu」を入力した場合
SELECT DISTINCT(term) FROM terms
WHERE MATCH (reading) -- ヨミガナ前方一致検索(ヒット)
AGAINST (CONCAT('*SS prefix_rk_search(reading, ',
mroonga_escape('gyu' AS script),
')') IN BOOLEAN MODE) OR
MATCH (term) -- 候補を緩く全文検索
AGAINST (CONCAT('*D+ ', mroonga_escape('gyu'))
IN BOOLEAN MODE)
ORDER BY term LIMIT 10; -- ソート
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 71

同義語展開
同義語
同じ意味だが表記が異なる語
例:「刺身」と「お造り」
どの表記でもヒットして欲しい
同義語展開→同義語すべてでOR検索
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 72

同義語展開
実装方法
同義語管理テーブルを作成
クエリー内の同義語を展開
展開後のクエリーで検索
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 73

同義語展開:Mroonga
テーブル定義
CREATE TABLE synonyms (
term varchar(255),
-- 展開対象の語
synonym varchar(255), -- 同義語
INDEX (term)
-- 高速化と精度向上
COMMENT 'normalizer "NormalizerAuto"'
) ENGINE=Mroonga DEFAULT CHARSET=utf8mb4;
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 74

同義語展開
データ例
INSERT INTO synonyms
-- 「刺身」を「刺身 OR お造り」に展開
VALUES ('刺身', '刺身'),
('刺身', 'お造り'),
-- 「お造り」を「お造り OR 刺身」に展開
('お造り', 'お造り'),
('お造り', '刺身');
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 75

同義語展開
データ管理のポイント
普通のテーブルなので管理が楽
追加・削除・更新が楽
ダンプ・リストアもいつも通り
レプリケーションもいつも通り
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 76

同義語展開:Mroonga
確認方法
SELECT mroonga_query_expand(
'synonyms',
-- テーブル名
'term',
-- 展開対象のカラム名
'synonym',
-- 対応する同義語のカラム名
'居酒屋 刺身' -- クエリー
);
-- '居酒屋 ((刺身) OR (お造り))'
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 77

同義語展開:Mroonga
検索方法
SELECT title FROM entries
WHERE
MATCH (title)
-- '*D+ 居酒屋 OR ((刺身) OR (お造り))'になる
AGAINST (mroonga_query_expand('synonyms',
'term',
'synonym',
'*D+ 居酒屋 刺身')
IN BOOLEAN MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 78

類似文書検索
検索クエリーは文書そのもの
キーワードではない
関連エントリーの提示に使える
メタデータがあるなら組み合わせる
→精度向上
メタデータ:タグ・行動履歴など
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 79

類似文書検索:Mroonga
インデックス定義
CREATE TABLE entries (
-- ...
FULLTEXT INDEX (content)
-- TokenMecabを使わないと精度がでない
-- 必要なときだけカスタマイズ!
COMMENT 'tokenizer "TokenMecab"'
) -- ...
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 80

類似文書検索:Mroonga
検索方法
SELECT title
FROM entries
WHERE
MATCH (content)
-- ↓ 既存文書の内容をそのまま指定
AGAINST ('...Groongaで高速全文検索!...'
IN NATURAL LANGUAGE MODE);
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 81

類似文書検索:Mroonga
結果例
クエリー:
...Groongaで高速全文検索!...
ヒット例:
...Mroongaで高速全文検索!...
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 82

全文検索システムの実装
まとめ
全文検索
キーワードハイライト
周辺テキスト表示
オートコンプリート
同義語展開
関連文書の表示
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 83

全文検索システムの実装
次の一歩
構造化データ対応
オフィス文書・HTMLなど
対応に必要な処理
テキスト抽出
メタデータ抽出 (例:タイトル・更新日時)
スクリーンショット作成 (なおよい)
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 84

抽出ツール
Apache Tika
Apache Luceneのサブプロジェクト
対応フォーマット数が多い
ChupaText
Groongaのサブプロジェクト
スクリーンショット作成対応
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 85

ChupaText
対応フォーマット
Word/Excel/PowerPoint
ODT/ODS/ODP (OpenDocument)
PDF/HTML/XML/CSV/...
インターフェイス
HTTPとコマンドライン
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 86

ChupaText:インストール
DockerかVagrantを使うのが楽
https://github.com/ranguba/chupa-text-docker
https://github.com/ranguba/chupa-text-vagrant
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 87

ChupaText:Docker
% GITHUB=https://github.com
% git clone \
${GITHUB}/ranguba/chupa-text-docker.git
% cd chupa-text-docker
% docker-compose up --build
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 88

ChupaText:使い方
% curl \
--form data=@XXX.pdf \
http://localhost:20080/extraction.json
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 89

ChupaText:結果例
{
}
"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であることを明記
}
}
]
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 90

ChupaText:Web UI
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 91

ChupaText:Web UI抽出例
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 92

ChupaText:Web UI抽出例
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 93

ChupaText:Vagrant
% GITHUB=https://github.com
% git clone \
${GITHUB}/ranguba/chupa-text-vagrant.git
% cd chupa-text-vagrant
% vagrant up
使い方はDocker版と同じ
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 94

ChupaText:活用例
抽出したテキスト
Mroongaへ挿入
抽出したメタデータ
Mroongaへ挿入
絞り込みに活用
作成したスクリーンショット
検索結果表示時に掲載
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 95

まとめ
MariaDBの全文検索まわり
全文検索システム実装例を紹介
構造化データの対応方法を紹介
ChupaText
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 96

扱わなかった話題
運用について
障害対策・レプリケーション
チューニング
Groongaの機能を直接使う方法
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Page: 97

サポートサービス紹介
導入支援 (設計支援・性能検証・移行支援・…)
開発支援
(サンプルコード提供・問い合わせ対応・…)
運用支援 (障害対応・チューニング支援・…)
問い合わせ先:
https://www.clear-code.com/contact/?
type=groonga
MariaDBとMroongaで作る 全言語対応 超高速全文検索システム
Powered by Rabbit 2.2.2

Other slides

Apache Arrow Apache Arrow
2017-06-13
Apache Arrow Apache Arrow
2017-05-28
Mroonga! Mroonga!
2015-10-30