FULLTEXT

この投稿は3年半前の記事です。 情報が古くなっている可能性があるので、その点ご了承ください。
2013 年 10 月 22 日 1,281日前)
3,304文字 (読了時間8分)

SPONSORED LINK

生活に終われ、疲弊しきった不肖高橋です。海風薫る千葉の田舎町から大都会東京のコンクリートジャングルへと一人ゲルマン民族大移動を毎日繰り返した結果、加齢臭が強くなってきました。

昔は総武線でビール飲んでいるオジサンを見るたびに汚いものを見るような視線を投げていたのですが、いまその視線がブーメランのように私を射抜いていきます。

木の一族 (新潮文庫)

木の一族 (新潮文庫) [書籍]

著者佐伯 一麦

出版社新潮社

出版日1997-03

商品カテゴリー文庫

ページ数186

ISBN410134213X

Supported by amazon Product Advertising API

さて、「電車でビール飲んでる」と無意味な嘘をついたところで、おもむろに全文検索について。

以前WordPressで大規模データを扱う場合のTipsという記事でも触れたのですが、WordPressの検索はLIKE検索なので、記事が数千件を超えたあたりから少しずつ遅くなってきます。今回はその解決策として日本語全文検索をやってみます。

ぱくたそより
ぱくたそより

アプローチ:FULLTEXTインデックスだけでなんとかする

全文検索には幾つかの手法がありますが、MySQLに元々そなわっているFULLTEXTインデックスと全文検索関数を利用します。5.6からはinnodbでもOKになったはず。

アプローチの仕方は次の通りです。

  1. FULLTEXTインデックスを有効にするためには対象となるカラムの文字列が分かち書きされている(半角スペースとかカンマで区切られている)必要がある
  2. 日本語オワタ\(^o^)/
  3. じゃあ、分かち書きしてどっか保存しておくか
  4. 分かち書きってどうやって作るの? ← イマココ

という具合に「いかにして分かち書きするか」という壁が立ちはだかってきました。

分かち書きをMecabで作る

対象となるのはブログ記事本文なので、それなりに長い文章を用意します。今回は青空文庫の室生犀星『みずうみ』を利用してみました。

サーバになにかをインストールするのは面倒なので、とりあえずYahooテキスト解析APIを使用してみます。

すると、Request Entity Too Large つまり、「送ってくる文章長過ぎ」というエラーが返ってきました。そりゃそうだよね。

となると自分のサーバに分かち書きができるソフトをインストールする必要が出てきます。今回はMecabとそのPHPバインディングであるphp-mecabを利用します。

インストールはここら辺を参考にしてください。

インストールの注意点は次の通りです。

  • mecabはUTF-8でインストールし、IPA辞書もUTF-8で入れましょう。
  • わかんなくなったらmecabのインストールディレクトリにmecabrcがあるので、それを見てみましょう。
  • php-mecabのインストールでこける人がいるようですが、pearじゃなくてpeclコマンドかもしれません。
  • php-mecabはマニュアルがないのですが、Githubにあるmecab.cを読むと関数の戻り値などが記載されてます。
  • php-mecabの利用サンプルは同じくGithubのexamplesフォルダにあります。

で、mecabをPHPから使えるようになったらこんな処理を行います。

  1. WordPressの投稿テーブルはpost_content_filteredというカラムが余っているので、ここFULLTEXTインデックスを貼る
  2. 投稿保存時に投稿本文とタイトル、抜粋を全部合体して、タグとショートコードを除去したのち、Mecabで分かち書きにした上でpost_content_filteredに保存
  3. WordPressの検索クエリはLIKEを使うので、ここをMATCH(post_content_filtered) AGAINST('ほにゃらら')構文に変更

詳細を書くのが面倒なので、上記の処理をクラスにまとめたものをGistに上げておきました。確認してみてください。

WP_Fulltext_Search

あと、書き忘れていましたが、MySQLの全文検索は初期設定だと4文字未満を無視するという鬼畜仕様なので、これを変える必要があります。my.cnfに記載してください。

# mysqldのところに書く
ft_min_word_len=1

この設定は一番最初にやっておく必要があります。懸命な読者諸氏は「じゃあ最初に書いておけよ」と思われたことでしょう。すみません。

お手数ですが、MySQLを再起動してインデックスを消去してください。上記クラスはお利口なので、インデックスを勝手に貼ってくれます。

なんのベンチマークもとっておりませんが、10万件のレコードで10秒近くかかっていた検索があっという間に完了するようになったのではないかと思われます。

これまで投稿したデータについては、Cron処理などで地道に書き換えていくのがよいでしょう。

残る課題がたくさん

さて、こうしてMySQLの全文検索機能がめでたく使えるようになったのですが、実用的なレベルになるには次の課題があります。

ストップワードどうする?

Mecabでなにも考えずに分かち書きをすると、「の」などの助詞なども入ってきます。これはストップワードとして除外すべき単語ですが、MySQLのデフォルトストップワードリストには入っていません。なので、このメンテナンス方法を考えなければいけません。

設定でどうにかできるみたいではあるのですが、まったく試していません。

Mecabの辞書どうする?

Mecabは分かち書きを行うときに辞書を使うのですが、辞書型のアプローチはどうも未知語に弱いようです。固有名詞や流行語など、追加した方が利便性が高いでしょう。

この辞書をメンテナンスする方法を考えないと、全文検索を導入が完了したとは言えないですね。基本的には決まった形式でCSVを作ってコンパイルすればよいようなのですが、毎回手作業ではやってらんねーというのもあるでしょうし、Webサービスの場合はなんとかして自動化したいところだと思われます。

クエリの調整

全文検索で使われるMATCH(post_content_filtered) AGAINST('ほにゃらら')構文には色んなオプションがあります。今回はとりあえず検索クエリを半角スペースでくっつけるだけという簡単な道を選びましたが、文章を解析したりとか、色んなアプローチがあるはずです。ここを工夫すると、「なにこの検索便利!」という結果になるんじゃないでしょうか。

 

書き始めた当初は「mroongaをインストールするより簡単だろう」という考えから、「WordPressでお手軽全文検索」と名付けるところでしたが、Mecabをインストールしている時点でさしてお手軽でもないと考え直しました。

そのうちmroongaを導入したり、Mecabの他の使い方を書いてみようと思います。では、最後に関連リンクを挙げて終わります。

エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド

エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド [書籍]

著者奥野 幹也

クリエーター奥野 幹也

出版社技術評論社

出版日2010 年 6 月 12 日

商品カテゴリー大型本

ページ数520

ISBN4774142948

Supported by amazon Product Advertising API

 

フォローしてください

ここで会ったのもなにかの縁。
高橋文樹.comの最新情報を見逃さないためにもフォローをお願いします。
めったに送らないメルマガもあります。

SPONSORED LINK

この記事について

この記事はが2013 年 10 月 22 日にプログラミングの記事として公開しました。

高橋先生の電子書籍

高橋先生の電子書籍

Amazonで電子書籍も買えます。

好きな言葉

ふう! 伝記作家って、悪魔だな。

— スティーブン・ミルハウザー

高橋先生の処女作

『途中下車』高橋文樹

2001年幻冬舎NET学生文学大賞受賞作です。

Web制作やります

Web制作やります

Web制作のご依頼は株式会社破滅派へ

不定期メルマガ

高橋文樹.comでは、不定期でニュースレターを配信しています。滅多に送らないので是非購読してください。

高橋文樹.comではプライバシーポリシーに準じて登録情報を取り扱います。