Kouhei Sutou
kou****@clear*****
2016年 6月 7日 (火) 14:15:45 JST
須藤です。 In <40321****@web10*****> "[groonga-dev,04050] pgroongaの@@演算子が効かない" on Tue, 7 Jun 2016 13:56:45 +0900 (JST), 清河 宗一朗 <iftha****@yahoo*****> wrote: > また、idx_t_tempインデックスを作成しなくても、下記SQLが動作したのです > が、 > そういうものなのでしょうか。 > select * from t_temp where for_search %% 'pgroonga'; > select * from t_temp where for_search %% 'postgres'; はい、そういうものです。 PostgreSQLではオプティマイザーの判断によって同じ演算子を使っ た条件でもインデックスを使ったり使わなかったり(= シーケンシャ ルスキャン)します。 インデックスがない場合は必ずシーケンシャルスキャンになるので すが、PGroongaが提供する演算子(のほとんど)はシーケンシャル スキャンでも動くようになっているので、インデックスがなくても 動きます。 > => select * from t_temp where for_search @@ 'pgroonga OR postgres'; > id | for_search > ----+------------ > (0 行) これは@@をシーケンシャルスキャンで実行しようとしているからで す。PGroongaが提供する@@はシーケンシャルスキャンをサポートし ているのですが、演算子を探す優先順位の関係でPGroongaが提供す る@@ではなくPostgreSQLが提供する@@が使われていてこうなります。 PostgreSQLが提供する@@は「X OR Y」という構文ではなく「X | Y」 という構文を使います。これはtextをtsqueryという型に変換する ときに使われている構文です。 https://www.postgresql.org/docs/current/static/datatype-textsearch.html#DATATYPE-TSQUERY そのため、「pgroonga OR postgres」は「pgroonga」または 「postgres」ではなく「pgroonga OR postgres」そのものを検索し ます。なのでヒットしません。 説明が長くなってしまいましたが、ようはPostgreSQLが提供する@@ ではなくPGroongaが提供する@@を使うようにすればよいです。 どうすればよいかというと SET search_path TO "$user",public,pgroonga,pg_catalog; を実行してください。これでそのセッションではPGroongaの@@を優 先的に使うようになります。 セッションだけでなく永続的に設定する場合は次のようにします。 ALTER DATABASE データベース名 SET search_path TO "$user",public,pgroonga,pg_catalog; 接続するユーザーが決まっているなら ALTER ROLE ユーザー名 SET search_path TO "$user",public,pgroonga,pg_catalog; でもよいです。 という説明を http://pgroonga.github.io/ja/reference/operators/query.html の「シーケンシャルスキャン」のところに書かないとなぁと思って いるのですがまだ書けていません。。。 -- 須藤 功平 <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