Kouhei Sutou
kou****@clear*****
2015年 5月 9日 (土) 19:13:35 JST
須藤です。 少し高度な使い方になるのですが、selectの回数を減らす方法があ るので補足します。 In <20150****@clear*****> "[groonga-dev,03210] Re: selectとin_valuesの制限事項について" on Fri, 08 May 2015 21:59:06 +0900 (JST), Kouhei Sutou <kou****@clear*****> wrote: > select \ > --table Keywords \ > --filter '_key *T "Groonga and Mroonga are good!"' \ > --output_columns _key > # -> ["groonga", "mroonga"] > > select \ > --table Users \ > --match_columns keywords \ > --query 'groonga OR mroonga' > # -> [["user1", ["groonga", "mysql"]], > # ["user3", ["mroonga"]]] ここで1つ目のselectの結果を2つ目のselectの条件に使っているん ですが、次のようにsub_filter()(*)を使うと一回のselectで実現 できます。 (*) http://groonga.org/ja/docs/reference/functions/sub_filter.html --- select \ --table Users \ --filter 'sub_filter(keywords, "_key *T \\"Groonga and Mroonga are good!\\"")' # -> [["user1", ["groonga", "mysql"]], # ["user3", ["mroonga"]]] --- sub_filter()はSQLでいう WHERE xxx_id IN (SELECT id FROM xxx WHERE ...) のようなことができる機能です。 sub_filter()を使えるのは↑のSQLのように 1. 条件が参照型のカラム (別のテーブルのプライマリーキーを参照しているカラム) に対するIN 2. サブSELECTの結果は参照されているテーブルのプライマリー キー(レコード)の集合 の場合だけです。 今回のケースではUsers.keywordsがKeywordsテーブルの参照型で、 それで絞り込みたいので1.を満たしています。また、 「_key *T "..."」の結果で絞り込んだ結果はKeywordsテーブルの レコードなので2.も満たしています。 補足: ↑の説明は少し簡略化していて、実はsub_filterを使うにはもうひ とつ条件があります。参照されているテーブルから元のselectのテー ブルへのインデックスがあること、という条件です。今回の場合だと column_create Keywords users_keywords COLUMN_INDEX Users keywords がそれにあたります。 絵を書けばピンときやすいんですが、テキストでの説明だとこんな 感じなので省略しました。。。 sub_filter()は、他にも第二引数は「文字列」でfilterと同じ書式 の条件を書かないといけないので「\」や「"」のエスケープが必要 になるなど、使い方が難しい機能ではあるのですが、高度なことが できるので参考までに紹介しました。 動かせるスキーマとデータとselectは次の通りです。 --- table_create Articles TABLE_HASH_KEY ShortText column_create Articles content COLUMN_SCALAR Text table_create Keywords TABLE_PAT_KEY ShortText \ --normalizer NormalizerAuto # 表示するときは正規化しない状態で表示したいならあると便利 # 例: 「groonga」ではなく「Groonga」と表示したい # column_create Keywords label COLUMN_SCALAR ShortText table_create Users TABLE_HASH_KEY ShortText column_create Users keywords COLUMN_VECTOR Keywords column_create Keywords users_keywords COLUMN_INDEX Users keywords load --table Articles [ {"_key": "article1", "content": "Groonga and Mroonga are good!"}, {"_key": "article2", "content": "MySQL and PostgreSQL are good!"}, {"_key": "article3", "content": "Groonga + MySQL = Mroonga!"} ] load --table Users [ {"_key": "user1", "keywords": ["Groonga", "MySQL"]}, {"_key": "user2", "keywords": ["MySQL"]}, {"_key": "user3", "keywords": ["Mroonga"]} {"_key": "user4", "keywords": ["PostgreSQL"]} ] select \ --table Articles \ --filter '_key == "article1"' \ --output_columns content # -> "Groonga and Mroonga are good!" select \ --table Keywords \ --filter '_key *T "Groonga and Mroonga are good!"' \ --output_columns _key # -> ["groonga", "mroonga"] select \ --table Users \ --filter 'sub_filter(keywords, "_key *T \\"Groonga and Mroonga are good!\\"")' # -> [["user1", ["groonga", "mysql"]], # ["user3", ["mroonga"]]] --- -- 須藤 功平 <kou****@clear*****> 株式会社クリアコード <http://www.clear-code.com/> Groongaベースの全文検索システムを総合サポート: http://groonga.org/ja/support/ パッチ採用 - プログラミングが楽しい人向けの採用プロセス: http://www.clear-code.com/recruitment/ プログラミングが好きな学生のための勉強会: http://www.seplus.jp/sezemi/