[groonga-dev,03213] Re: selectとin_valuesの制限事項について

Back to archive index

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/




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