[groonga-dev,01550] Re: 特殊記号混じりの前方一致検索について

Back to archive index

mail_babir****@yahoo***** mail_babir****@yahoo*****
2013年 7月 27日 (土) 12:33:51 JST


田辺です。

> 別の案を思いつきました!
> mroonga_escape()みたいな関数を提供して、
> 
>   SELECT ... WHERE
>     MATCH (...) AGAINST (mroonga_escape("(仮)") IN BOOLEAN MODE);
> 
> というようにするのはどうでしょうか?これで「(仮)」そのものを
> 検索するイメージです。(「(...)」をグループ化する書き方とし
> て認識しない。)
> 
> 前に出ていた「クエリー全体を全部自動でエスケープ」案と違って、
> 関数なのでエスケープする範囲をアプリケーションで制御できます。
> 例えば、
> 
>   AGAINST (mroonga_escape("(仮)") + "*" IN BOOLEAN MODE)
> 
> とすれば「*」という特殊な文字を使って前方一致検索を使いつつ、
> 特殊文字を使いたくない範囲だけ特殊文字を無効にできます。

これは良さそうですね!

単純な前方一致検索の用途で、()が含まれているせいでパースエラーが出ていることが結構あるので、便利だと思います。

場合によっては複数回エスケープ関数を使うことがありそうなので、関数名はe()くらい短くできるといいですね。


ただ、また話を戻してしまって恐縮なのですが、
「+(仮)* -(笑)」のようなクエリで「(仮)が前方一致しつつ、(笑)は含まない」という検索条件をユーザが直接指定できるようにさせる場合、アプリケーション側では「半角スペースでワード分割して、前方一文字に+-を含む場合はそれを外し、後方一文字に*がある場合はそれも外したうえで、mroonga_escape()で括って、先ほど外した文字を付け直す」ということになるかと思います。

これはさすがに手順が煩雑なので、もう少し上手い方法を正規表現で書くなり、「¥¥」でのエスケープをすることになるとは思いますが。

ただ、「使いたい特殊文字が所定の位置にあることをアプリケーション側で特定して、それ以外の部分にある特殊文字だけをエスケープする」という処理は必要になってしまうかと思います。

これはアプリケーション側の責任、と言われてしまうと仕方がないのですが、myisamの場合、以前検証頂いた結果のように上記のクエリを直接mysqlに流しても正確に検索ができるんですね。
そして、mysql自体のマニュアルを確認しても()+-*~><などの特殊文字をエスケープするように指示している記述が見当たらないです。

この点から考えると、mysqlとしてはin boolean modeで有効になる特殊文字については、特段エスケープ処理をしなくても動作する、という想定になっているような気がするのですが、どうでしょうか。

innodbでの挙動が、ft_min_word_len=1の場合でも前回テスト頂いた結果と同じならば、ストレージエンジンによって挙動が違うということで間違いないですが、仮にmyisamと同等の結果が得られるようになっている場合は、mroongaもその挙動に合わせられる方が望ましいと思います。

あと、こじつけ的な気もしますが、mysqlで全文検索といえばmyisamという認識が一般的と思うので、その挙動に合わせる点では問題はないと思っています。

・innodbが全文検索に対応したのがmysql5.6以降なので、そもそもmyisamの利用者が圧倒的多数と思われる
・もともと全文検索自体はmyisam固有の機能だったので、innodbよりmyisamに合わせる方が後方互換性があると言えそう
・myisamに合わせている限り、少なくとも想定外の検索結果になるということは考えにくい

なので、メリットはあってもデメリットは少ないと思うのです。
(sennaからの移行やgroongaの実装との兼ね合いまで考えると話は変わってきそうですが)



自動エスケープというよりは、特殊文字の解析方法をmyisamに合わせることができれば、より自然でいいかと思います。

myisamの実装を見て、似た実装ができそうなら引き続き検討頂けると有り難いです。


mroonga_escape()については、あれば確実に便利な関数だと思うので、myisamの挙動の件とは別に実装して頂けると嬉しいです。
(ユーザに特殊文字を使わせたくない場合に、予めその関数でラッピングしておくという使い方もできるので)


しつこく蒸し返して恐縮ですが、特殊文字の解析挙動が合えば、mroongaの導入にあたっての障壁がより低くなることは間違いないと思う(どうやってエスケープしようという点で悩まなくて済むし、後になってエスケープが必要なことを知って慌てることもない)ので、実現可能であれば、ぜひお願いしたいと思います。


田辺公平




groonga-dev メーリングリストの案内
Back to archive index