Y-Ken Studio

新しもの好きのデータエンジニアが四方山話をお届けします。

mroongaで特殊記号を用いた全文検索を行うときのエスケープ方法

mroongaで()~+><-*などの記号を含んだ文字列を検索しようとすると、以下のエラーが起きます。
ERROR 1064 (42000): failed to parse fulltext search keyword

本日はその対処法を紹介します。

エスケープ方法

特別な意味を持つ記号を検索する場合

()~+><-*などの記号を検索する場合は、ダブルクォートで囲いましょう。

以下、「<meta>」という検索を行う際のエスケープ方法です

-- 動かない
SELECT COUNT(*) FROM test_table WHERE MATCH(body) AGAINST('*D+ <meta>' IN BOOLEAN MODE);
ERROR 1064 (42000): failed to parse fulltext search keyword: <*D+ <meta>>: <Syntax error! (<meta>)>

-- 動く
SELECT COUNT(*) FROM test_table WHERE MATCH(body) AGAINST('*D+ "<meta>"' IN BOOLEAN MODE);

ダブルクォートを含む検索をしたい場合

以下のように、2重でエスケープする(「\」をもう一つ追加する)必要があります。
理由としては、MySQLで解釈された後にgroongaへ渡されるという2回の処理を挟むためです。

以下、「aa"aa」という検索を行う際のエスケープ方法です

-- 動かない
SELECT COUNT(*) FROM test_table WHERE MATCH(body) AGAINST('*D+ "aa\">aa"' IN BOOLEAN MODE);
ERROR 1064 (42000): failed to parse fulltext search keyword: <*D+ "aa">aa">: <Syntax error! ("aa">aa")>

-- 動く
SELECT COUNT(*) FROM test_table WHERE MATCH(body) AGAINST('*D+ "aa\\">aa"' IN BOOLEAN MODE);

補足

Tritonnよりも厳密なエラー処理をmroongaでは行っているため、このようなエラーとなります。
幸いなことに、ダブルクォートで囲う記述はTritonnでもサポートされています。
mroongaへ移行する前に書き換えておけば、アップグレードがスムーズですね。

参考記事

http://sourceforge.jp/projects/groonga/lists/archive/dev/2013-April/001328.html http://sourceforge.jp/projects/groonga/lists/archive/dev/2011-January/000441.html