共用サーバの MariaDB で全文検索を使う

MariaDB で全文検索できるようになって久しいですが、デフォルトのエンジンは半角スペース分かち書きしか認識してくれないようです。英語ならばそれで問題ないのでしょうが、日本語のように空白文字を書かない言語だと文や段落が登録されてしまい、うまくありません。

ぐぐってみると日本語の分かち書きや N-gram に対応した全文検索エンジンがあるようですが、Xserver のような共用サーバでは設定を変えるわけにもいかず、ちょっと困ってしまいました。

そこで、N-gram の考え方に戻って強制的に日本語を分かち書きしてみたところ、うまく行ったので備忘録として記録しておきます。

アイデアは以下のようになります。

  • Xserver のデフォルト設定に従い、3-gram を構成する。
  • 具体的には文章を3文字ごとに区切って強制的に半角スペースを間に入れる。
  • 検索時も3文字ごとに区切った文字列を作成し、AND 検索する。

■全文検索用カラムの追加

カラム fullsearch に全文検索インデックスを設定します。

ALTER TABLE mytable ADD COLUMN fullsearch TEXT;
ALTER TABLE mytable ADD FULLTEXT INDEX mytable_fullsearch (fullsearch);

MariaDBは mecab や ネイティブな ngram パーサーをインストールすることが可能ですが、共用サーバでは難しいので、ここではデフォルトのパーサーを利用することとしています。

■3-gram の構成

3-gramでは、例えば「本日は晴天なり」という文があったら、以下のような文字列を構成します。

  • 本日は
  • 日は晴
  • は晴天
  • 晴天な
  • 天なり

UPDATE mytable SET fullsearch="本日は 日は晴 は晴天 晴天な 天なり" WHERE id=:id;

■検索時の文字列

検索時も 3-gram に分解して検索します。例えば「晴天なり」と入力した場合、

  • 晴天な
  • 天なり

のような文字列を作成します。後はこれらの文字列を AND 検索するようにします。

SELECT id FROM mytable MATCH (fullsearch) AGAINST ("+晴天な +天なり" IN BOOLEAN MODE); 

入力に複数の単語を指定可能にする場合は OR 検索したいでしょうから、

SELECT id FROM mytable MATCH (fullsearch) AGAINST ("(+晴天な +天なり) (+本日は)" IN BOOLEAN MODE);

のような SQL を発行することになると思います。

本当は 1-gram もしくは 2-gram としたいところですが、共用サーバの制約上仕方がないです。

投稿者について
みのしす

小さいときは科学者になろうとしたのに、その時にたまたま身に着けたプログラミングで未だに飯を食っているしがないおじさんです。(年齢的にはもうすぐおじいさん)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です