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の導入にあたっての障壁がより低くなることは間違いないと思う(どうやってエスケープしようという点で悩まなくて済むし、後になってエスケープが必要なことを知って慌てることもない)ので、実現可能であれば、ぜひお願いしたいと思います。 田辺公平