[groonga-dev,03786] Re: エスケープ文字に関して

Back to archive index

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




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