sub_filter は filter_string を scope のコンテキストで評価します。
sub_filter は select コマンドの --filter 内でのみ指定できます。
使い方を示すために使うスキーマ定義とサンプルデータは以下の通りです。
サンプルスキーマ:
実行例:
table_create Comment TABLE_PAT_KEY UInt32
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Comment name COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Comment content COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
table_create Blog TABLE_PAT_KEY ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Blog title COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Blog content COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Blog comments COLUMN_VECTOR Comment
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Comment blog_comment_index COLUMN_INDEX Blog comments
# [[0, 1337566253.89858, 0.000355720520019531], true]
table_create Lexicon TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Lexicon comment_content COLUMN_INDEX|WITH_POSITION Comment content
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Lexicon comment_name COLUMN_INDEX|WITH_POSITION Comment name
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Lexicon blog_content COLUMN_INDEX|WITH_POSITION Blog content
# [[0, 1337566253.89858, 0.000355720520019531], true]
サンプルデータ:
実行例:
load --table Comment
[
{"_key": 1, "name": "A", "content": "groonga"},
{"_key": 2, "name": "B", "content": "groonga"},
{"_key": 3, "name": "C", "content": "rroonga"},
{"_key": 4, "name": "A", "content": "mroonga"},
]
# [[0, 1337566253.89858, 0.000355720520019531], 4]
load --table Blog
[
{"_key": "groonga's blog", "content": "content of groonga's blog", comments: [1, 2, 3]},
{"_key": "mroonga's blog", "content": "content of mroonga's blog", comments: [2, 3, 4]},
{"_key": "rroonga's blog", "content": "content of rroonga's blog", comments: [3]},
]
# [[0, 1337566253.89858, 0.000355720520019531], 3]
ユーザー'A'のコメント
実行例:
select Blog --output_columns _key --filter "comments.name @ \"A\" && comments.content @ \"groonga\""
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_key",
# "ShortText"
# ]
# ],
# [
# "groonga's blog"
# ],
# [
# "mroonga's blog"
# ]
# ]
# ]
# ]
上記のクエリを実行すると、"groonga's blog"だけでなく、"mroonga's blog"もマッチします。ユーザー"A"は"mroonga's blog"に対しては"groonga"に言及していないので、これは意図していない結果です。
sub_filterなしでは、以下の条件が満たされます。
すくなくとも一つはユーザー"A"がコメントしたレコードがある。
すくなくとも一つは"groonga"について言及したレコードがある。
実行例:
select Blog --output_columns _key --filter 'sub_filter(comments, "name @ \\"A\\" && content @ \\"groonga\\"")'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_key",
# "ShortText"
# ]
# ],
# [
# "groonga's blog"
# ]
# ]
# ]
# ]
一方、上記のクエリは意図した結果を返します。これは、sub_filterの引数がcommentsカラムのコンテキストで評価されるからです。
sub_filterは以下の条件が満たされていることを要求します。
ユーザー"A"が"groonga"について言及しているレコードがある。
必須引数は二つあります。 scope と filter_string です。
select コマンドの table パラメーターで指定したテーブルが持つカラムを指定します。このカラムには制限があります。制限については後述します。 filter_string はこのカラムの文脈で評価されます。これは、 filter_string は select --table カラムの型 --filter フィルター文字列 というように評価されるということです。
指定したカラムの型はテーブルでなければいけません。言いかえると、カラムの型は参照型でなければいけないということです。
カラム1.カラム2.カラム3...カラムN という構文でカラムを数珠つなぎにできます。例えば、 user.group.name とできます。
select コマンドの table 引数については select-table を参照してください。
sub_filter は1つでもレコードがマッチしたかどうかを返します。もし、1つ以上のレコードがマッチしたら true を返します。1つもマッチしなかったら false を返します。