本文へスキップ
`Ctrl`+`K`

# 7.15.29. `sub_filter`

## 7.15.29.1. 概要

`sub_filter` は `filter_string` を `scope` のコンテキストで評価します。

`sub_filter` は select コマンドの `--filter` 内でのみ指定できます。

## 7.15.29.2. 構文

`sub_filter` は2つの引数が必要です。 `scope` と `filter_string` です。

    sub_filter(scope, filter_string)

## 7.15.29.3. 使い方

使い方を示すために使うスキーマ定義とサンプルデータは以下の通りです。

サンプルスキーマ:

実行例:

    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]

ブログのエントリを抽出する `sub_filter` 関数の使用例です。

実行例:

    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"について言及しているレコードがある。

## 7.15.29.4. 引数

必須引数は二つあります。 `scope` と `filter_string` です。

### 7.15.29.4.1. `scope`

`select` コマンドの `table` パラメーターで指定したテーブルが持つカラムを指定します。このカラムには制限があります。制限については後述します。 `filter_string` はこのカラムの文脈で評価されます。これは、 `filter_string` は `select --table カラムの型 --filter フィルター文字列` というように評価されるということです。

指定したカラムの型はテーブルでなければいけません。言いかえると、カラムの型は参照型でなければいけないということです。

`カラム1.カラム2.カラム3...カラムN` という構文でカラムを数珠つなぎにできます。例えば、 `user.group.name` とできます。

`select` コマンドの `table` 引数については table を参照してください。

### 7.15.29.4.2. `filter_string`

スクリプト構文 の検索条件を指定します。これは `scope` のコンテキストで評価されます。

## 7.15.29.5. 戻り値

`sub_filter` は1つでもレコードがマッチしたかどうかを返します。もし、1つ以上のレコードがマッチしたら `true` を返します。1つもマッチしなかったら `false` を返します。

## 7.15.29.6. 参考

- select

- スクリプト構文