mysql+mroongaで全文検索

11
MySQL + Mroongaで全文検索 あかやま

Upload: yoyamasaki

Post on 09-May-2015

3.002 views

Category:

Software


7 download

DESCRIPTION

「MySQL勉強会 in 大阪(第6回)」 http://atnd.org/events/49005 で、あかやまさんに発表頂いた時の資料です。

TRANSCRIPT

Page 1: Mysql+Mroongaで全文検索

MySQL + Mroongaで全文検索 あかやま

Page 2: Mysql+Mroongaで全文検索

自己紹介

SE会社でSEとして勤務しています。

主に、お客様の社内、社外ポータルサイトの開発をメインに行っています。

3年前より、MySQLを使ったシステム開発をするようになりました。(MySQL5.5~)

それまでは、OracleとかPostgreSQLを使ったシステム開発がメインです。

MySQLやMroongaのエキスパートではありません。

Page 3: Mysql+Mroongaで全文検索

きっかけ

あるWEBサイトのリプレイスを担当することになりました。概要は、

• あるコンテンツを大分類、中分類などのジャンル別に登録して利用者へ表示させる。

• フリーワード検索機能も提供したい。当然、ひらがな、かたかな、全角、半角の違いは吸収してほしい。

• データの登録は、サイト運営者のみが行い。利用者からの投稿機能はない。

ちなみに現行システムは

• データベースは、PostgreSQLを利用。

• フリーワード検索機能も提供しているが、like検索を行っている。

「パズル」で検索しないと、「パズル&ドラゴンズ」はヒットしない。

検索対象カラムは、画面表示用のカラム と あいうえお順にソートするため ふりがな のカラムが存在している。

データ件数は 1000 件程度。 今後は、もっと増える予定。

Page 4: Mysql+Mroongaで全文検索

要件にあったものを探しましょう

フリーワード検索といえば

• Solr が有名なんだけど…

開発経験なし。 決められたスケジュール、予算では難しい。

データの移行も大変そう。

RDBにも全文検索という機能があるよね…

• Oracle … 予算の都合でNG(そもそも現行システムはPostgreSQLだし。)

• PostgreSQL

Senna → サイトが2010年以降更新されている様子もなし。ちょっと不安。

pg_bigram → なんか使えそう。 でも、要件にある ひらがな、カタカナ、全角、半角を吸収する方法は?

• MySQL

mroonga → 毎月、リリースがあり活発に活動されている。

collation の設定でひらがな、カタカナ、全角、半角を吸収できる。

MySQL + mroonga を使うことに決定。

Page 5: Mysql+Mroongaで全文検索

Mroonga とは、 (http://mroonga.org/ja/ より)

GroongaをベースとしたMySQLのストレージエンジン

Groonga独自のカラムストアを持つ列指向のデータベース

Tritonnの後継 (MySQLに全文検索ライブラリSennaを組み込んだもの)

MySQLのプラグインとして動作

MySQL公式バイナリに手を加えずにプラグインとして動的にロードして利用可能

2つの動作モードをサポート

ストレージモード

デフォルトモード。データストア、検索機能もすべてGroongaを使うモード。ただし、トランザクションなどの機能はなし

ラッパーモード

MyISAMやInnoDBに全文検索機能だけを追加するモード。

形態素解析、N-gram、空白区切り などのパーサーが用意されている。

Page 6: Mysql+Mroongaで全文検索

さっそく試してみましょう

環境 ※昨年のことのなので、情報は古いです。

• OSは、CentOS6、 mroonga のバージョンは、3.0.7

• Mroonga のサイトで配布されるパッケージは、MySQLのバージョンは5.1に対応したもののが配布されていました。 5.1はあまりにも古いし、UTF8の4バイト文字に対応していなので MySQL5.6 の組み合わせでソースからインストールすることに決定。

インストール

Mroongaのサイトをにあるインストール手順を参照し、必要なものを集めてインストール。

• mecab ・・・ 形態素解析で必要。

• Groonga ・・・ groongaのサイトのインストール手順を参照。

• MySQL ・・・ cmakeのオプションを確認しながら。英語なので悪戦苦闘。

• Mroonga ・・・ mroongaのサイトのインストール手順を参照。

• Groongaノーマライザー ・・・ groongaのサイトのインストール手順を参照。

※MySQL以外はインストール手順書が日本語だったのですんなりできました。 :-p

Page 7: Mysql+Mroongaで全文検索

さっそく試しみましょう

以下のようなテーブルを作ってみました。 (ラッパーモードの場合)

mysql> CREATE TABLE contents (

-> id INT PRIMARY KEY AUTO_INCREMENT,

-> title VARCHAR(255),

-> kana VARCHAR(255),

-> FULLTEXT INDEX (kana) COMMENT 'parser "TokenBigram"'

-> ) ENGINE = mroonga COMMENT = 'engine "innodb"' DEFAULT CHARSET utf8mb4 COLLATE=utf8mb4_unicode_ci;

mysql> INSERT INTO contents (title,kana) VALUES ("牛肉","ぎゅうにく");

mysql> INSERT INTO contents (title,kana) VALUES ("豚肉","ぶたにく");

mysql> INSERT INTO contents (title,kana) VALUES ("牛乳","ぎゅうにゅう");

mysql> INSERT INTO contents (title,kana) VALUES ("筍","たけのこ");

mysql> INSERT INTO contents (title,kana) VALUES ("数の子","かずのこ");

mysql> select * from contents;

+----+--------+--------------------+

| id | title | kana |

+----+--------+--------------------+

| 1 | 牛肉 | ぎゅうにく |

| 2 | 豚肉 | ぶたにく |

| 3 | 牛乳 | ぎゅうにゅう |

+----+--------+--------------------+

コメントでパーサを指定する

ENGINE は mroongaを

COMMENTでMySQLのエンジンを指定する。

COMMENTを指定しなかった場合は、

ストレージモードでテーブルが作成される。

Page 8: Mysql+Mroongaで全文検索

さっそく試しみましょう 検索結果

mysql> SELECT * FROM contents WHERE MATCH(kana) AGAINST("ぎゅう");

+----+--------+--------------------+

| id | title | kana |

+----+--------+--------------------+

| 1 | 牛肉 | ぎゅうにく |

| 3 | 牛乳 | ぎゅうにゅう |

+----+--------+--------------------+

2 rows in set (0.02 sec)

mysql>

mysql> SELECT * FROM contents WHERE MATCH(kana) AGAINST("ニク");

+----+--------+-----------------+

| id | title | kana |

+----+--------+-----------------+

| 1 | 牛肉 | ぎゅうにく |

| 2 | 豚肉 | ぶたにく |

+----+--------+-----------------+

2 rows in set (0.02 sec)

• 期待どおりの検索結果がでました。 ひらがな、かたかな が同一視されているのは MySQLのCOLLATEの設定が効いているためです。

• フリーワード検索なので、漢字が入力されることもあります。その場合の対応として mecab で漢字→かな変換をしています

Page 9: Mysql+Mroongaで全文検索

さっそく試しみましょう と思ったのですが。。。

mysql> SELECT * FROM contents WHERE MATCH(kana) AGAINST("タケノコ");

+----+-----------+--------------+

| id | title | kana |

+----+-----------+--------------+

| 4 | 筍 | たけのこ |

| 5 | 数の子 | かずのこ |

+----+-----------+--------------+

2 rows in set (0.02 sec)

• MySQLのリファレンスマニュアルでブール全文検索を参照。

(英語はしんどいので、5.6のマニュアルと5.1の日本語のマニュアルを並べてみる。)

mysql> SELECT * FROM contents WHERE MATCH(kana) AGAINST("タケノコ" IN BOOLEAN MODE);

+----+-------+--------------+

| id | title | kana |

+----+-------+--------------+

| 4 | 筍 | たけのこ |

+----+-------+--------------+

2 rows in set (0.02 sec)

trigram にしたら、「かずのこ」はヒットしなくなりましたが。 じゃ「きゅうり」と「ぎゅうにく」は?

Page 10: Mysql+Mroongaで全文検索

感想

はじめて使った見たのですが、インストールからDBの構築までは、はまることなくできました。

また、MySQLのプラグインとして動作するものなので、だめだったら使わなければいいという

気持ちで使い始めました。

利用するシーンとしては、今まで like検索していたもの、(商品名、人名)で遅いといわれた場合に

導入してみるのもいいかなぁと思います。

ただ、実際のシステムは、ここでご紹介したような単純なものではなかったので、ノイズが多くて

こまりました。(検索結果として出てほしくないものがでたり、でてほしいものがでないなど)

日本語って難しいですね。

その時も、ここでは紹介していない パーサーをつかってみたり、Groongaのトークナイザを使ったり

して乗り切ることができました。(細かいところまで手がとどく)

Page 11: Mysql+Mroongaで全文検索

参考サイト、ツール紹介

ツール

• MySQL Workbench ( http://dev.mysql.com/downloads/tools/workbench/ )

何かと便利。ちょっと重いかな?

• A5:SQL Mk-2 ( http://www.wind.sannet.ne.jp/m_matsu/developer/a5m2/ )

ER図の作成だけではなく、ER図のリバース生成ができます。

今回は、旧システムのデータベースの構成を確認するために、大活躍しました。

参考サイト

• gihyo.jp ( http://gihyo.jp/dev/clip/01/groonga/0001 )

2013年4月~2013年9月 連載記事がありました。

• Qiita ( http://qiita.com/tags/mroonga )