Kouhei Sutou
kou****@clear*****
2015年 12月 18日 (金) 00:15:54 JST
須藤です。 In <55734****@web30*****> "[groonga-dev,03777] Re: エスケープ文字に関して" on Thu, 17 Dec 2015 10:07:19 +0900 (JST), takah****@yahoo***** wrote: >> すみません、具体的なINSERTとSELECTとその結果を見せてもらえま >> せんか? 提供ありがとうございます。 > select mroonga_command('select --table mail --output_columns No,Subject,ToAdd,FromAdd,Cc,Bcc,Date,AttachedFile --query \' Subject:@\\\\\\\\ \' --limit 1 --cache no'); > > '[[[1],[["No","Float"],["Subject","ShortText"],["ToAdd","ShortText"],["FromAdd","ShortText"],["Cc","ShortText"],["Bcc","ShortText"],["Date","Time"],["AttachedFile","Int8"]],[1.0,"\\","","","","",0.0,0]]]' > > \ひとつしか入力していないのに「"\\"」重複して結果が取得出来ます。 これはJSONでは「\」は「\\」とエスケープして出力する必要があ るからです。↑の文字列をJSONとしてパースすると「\」になりま す。 > select mroonga_command('select --table mail --output_columns No,Subject,ToAdd,FromAdd,Cc,Bcc,Date,AttachedFile --query \' Subject:@"\" \' --limit 1 --cache no'); > > '[[[0],[["No","Float"],["Subject","ShortText"],["ToAdd","ShortText"],["FromAdd","ShortText"],["Cc","ShortText"],["Bcc","ShortText"],["Date","Time"],["AttachedFile","Int8"]]]]' > > "\"は何も取得出来ない。 \' Subject:@"\" \' はMySQLが解釈するときに ' Subject:@"" ' になります。つまり、空文字列にマッチするかという条件になりま す。 しかし、Groongaは空文字列をインデックスを使って検索すること はできないのでヒットするレコードはありません。 > select mroonga_command('select --table mail --output_columns No,Subject,ToAdd,FromAdd,Cc,Bcc,Date,AttachedFile --query \' Subject:@"(" \' --limit 1 --cache no'); > > '[[[1],[["No","Float"],["Subject","ShortText"],["ToAdd","ShortText"],["FromAdd","ShortText"],["Cc","ShortText"],["Bcc","ShortText"],["Date","Time"],["AttachedFile","Int8"]],[2.0,"(","","","","",0.0,0]]]' > > "("は取得出来る。 \' Subject:@"(" \' はMySQLが解釈するときに ' Subject:@"(" ' と解釈します。 "(" はGroongaが解釈して「(」を検索ワードとして扱います。よってヒッ トします。 > このあたりの仕様の差がわからずエスケープを使用する文字に関してエスケープの場合とダブルコーテーションの > パターンでどういった形が仕様なのかご教示頂ければ幸いで御座います。 ここの「エスケープの場合とダブルコーテーションのパターン」と いうのは http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#escape の \ (バックスラッシュ)以外はエスケープする代わりにクォートすることもできます。 のことを言っているんですよね? プログラムでエスケープする場合は「バックスラッシュでエスケー プ」すればよいです。ダブルコーテーションを使う必要はありませ ん。 たとえば \' Subject:@"(" \' は \' Subject:@\\\\( \' にすればいいです。 ダブルコーテーションは「フレーズ検索」という意味もあるので単 に検索キーワードに特殊文字を使いたいだけならエスケープする方 が適切です。 http://groonga.org/ja/docs/reference/grn_expr/query_syntax.html#phrase-search-condition-with-explicit-match-column -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/ リーダブルコードワークショップ: http://www.clear-code.com/services/code-reader/readable-code-workshop.html