# groonga - An open-source fulltext search engine and column store.

- 日本語

# 7.14.19. `sub_filter`

## 7.14.19.1. Summary

`sub_filter` evaluates `filter_string` in `scope` context.

`sub_filter` can be used in only `--filter` in select.

## 7.14.19.2. Syntax

`sub_filter` requires two arguments. They are `scope` and `filter_string`.

    sub_filter(scope, filter_string)

## 7.14.19.3. Usage

Here are a schema definition and sample data to show usage.

Sample schema:

Execution example:

    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]

Sample data:

Execution example:

    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]

Here is the simple usage of `sub_filter` function which extracts the blog entry commented by user 'A'.

Execution example:

    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"
    #       ]
    #     ]
    #   ]
    # ]

When executing the above query, not only "groonga's blog", but also "mroonga's blog". This is not what you want because user "A" does not mention "groonga" to "mroonga's blog".

Without sub_filter, it means that following conditions are met.

- There is at least one record that user "A" commented out.
- There is at least one record that mentioned about "groonga".

Execution example:

    select Blog --output_columns _key --filter 'sub_filter(comments, "name @ \\"A\\" && content @ \\"groonga\\"")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "groonga's blog"
    #       ]
    #     ]
    #   ]
    # ]

On the other hand, executing the above query returns the intended result. Because the arguments of sub_filter is evaluated in comments column's context.

It means that sub_filter requires the following condition is met.

- There are the records that user "A" mentions about "groonga".

## 7.14.19.4. Parameters

There are two required parameter, `scope` and `filter_string`.

### 7.14.19.4.1. `scope`

Specifies a column of the table that is specified by `table` parameter in `select`. The column has a limitation. The limitation is described later. `filter_string` is evaluated in the column context. It means that `filter_string` is evaluated like `select --table TYPE_OF_THE_COLUMN --filter FILTER_STRING`.

The specified column type must be a table. In other words, the column type must be reference type.

You can chain columns by `COLUMN_1.COLUMN_2.COLUMN_3...COLUMN_N` syntax. For example, `user.group.name`.

See table about `table` parameter in `select`.

### 7.14.19.4.2. `filter_string`

Specifies a search condition in Script syntax. It is evaluated in `scope` context.

## 7.14.19.5. Return value

`sub_filter` returns whether any record is matched or not. If one or more records are matched, it returns `true`. Otherwise, it returns `false`.

## 7.14.19.6. See also

- select
- Script syntax