# groonga - オープンソースのカラムストア機能付き全文検索エンジン

- English

# 7.15.20. `snippet`

## 7.15.20.1. 概要

この関数は対象テキスト中から検索キーワード周辺のテキスト（ `KWIC` 。 `KeyWord In Context` ）を抽出します。抽出されたテキストのことをスニペットと呼びます。

普通のWebアプリケーションにこの関数を使いたい場合、 snippet_html の方が適切かもしれません。 `snippet_html` はこの関数のHTML特化バージョンです。

## 7.15.20.2. 構文

`snippet` は少なくとも1つの引数が必須です。その引数はスニペット対象のテキストです。

    snippet(column, ...)

キーワード・開始タグ・終了タグのセットを1つ以上指定できます。

    snippet(column,
            "keyword1", "open-tag1", "close-tag1",
            "keyword2", "open-tag2", "close-tag2",
            ...)

デフォルトの開始タグと終了タグを指定した場合は、キーワードだけを指定できます。

    snippet(column,
            "keyword1",
            "keyword2",
            ...,
            {
              "default_open_tag": "open-tag",
              "default_close_tag": "close-tag"
            })

バージョン 11.0.9 で追加: デフォルトの開始タグ・終了タグを指定し、キーワードを省略した場合は、 snippet_html のように現在の条件から自動でキーワードを抽出します。

    snippet(column,
            {
              "default_open_tag": "open-tag",
              "default_close_tag": "close-tag"
            })

どの構文でも最後の引数にオプションを指定できます。

    snippet(column,
            ...,
            {
              "width": 200,
              "max_n_results": 3,
              "skip_leading_spaces": true,
              "html_escape": false,
              "prefix": null,
              "suffix": null,
              "normalizer": null,
              "default_open_tag": null,
              "default_close_tag": null,
              "default": null,
              "delimiter_pattern": null,
            })

## 7.15.20.3. 使い方

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

実行例:

    table_create Documents TABLE_NO_KEY
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Documents content COLUMN_SCALAR Text
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram  --normalizer NormalizerAuto
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Terms documents_content_index COLUMN_INDEX|WITH_POSITION Documents content
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Documents
    [
    ["content"],
    ["Groonga is a fast and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, groonga allows updates without read locks. These characteristics result in superior performance on real-time applications."],
    ["Groonga is also a column-oriented database management system (DBMS). Compared with well-known row-oriented systems, such as MySQL and PostgreSQL, column-oriented systems are more suited for aggregate queries. Due to this advantage, groonga can cover weakness of row-oriented systems."]
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 2]

`default_open_tag` オプションと `default_close_tag` オプションを指定してキーワードを指定しなかった場合、 `snippet` は `--query` と `--filter` で指定した条件から自動的にキーワードを抽出します。これは snippet_html と同じ挙動です。

以下の例は `--query "fast performance"` を使っています。この場合は、キーワードとして `fast` と `performance` を使います。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]" \
                                })' \
      --match_columns content \
      --query "fast performance"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, gro",
    #           "onga allows updates without read locks. These characteristics result in superior [performance] on real-time applications."
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

`--query "fast performance"` は最初のレコードの内容にだけマッチします。この `snippet` は、テキスト中からキーワード `fast` と `performance` の少なくともどちらか一方を含んでいるテキストのスニペットを抽出します。今回は2箇所抽出しています。そして、抽出したテキストのスニペット内にあるキーワードを `[` と `]` で囲みます。

テキスト部分の最大数はデフォルトで3です。これは `max_n_results` オプションでカスタマイズできます。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]", \
                                   "max_n_results": 1 \
                                })' \
      --match_columns content \
      --query "fast performance"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, gro"
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

`"max_n_results": 1` を指定したのでスニペットを1つだけ返しています。

テキストの断片の最大サイズは200バイトです。単位は文字数ではなくバイトです。挿入される `[` と `]` のバイト数はこのサイズの中には含まれません。この値は `width` オプションで変更できます。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]", \
                                   "width": 50 \
                                })' \
      --match_columns content \
      --query "fast performance"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search en",
    #           " result in superior [performance] on real-time appli"
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

`delimiter_regexp` オプションを使うと正規表現でスニペットの区切りを検出できます。英語の文の場合、対象の文の中のテキストだけを使いたい場合は `\.\s*` を指定します。文字列の中では `\` をエスケープしないといけないことに注意してください。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]", \
                                   "delimiter_regexp": "\\\\.\\\\s*" \
                                })' \
      --match_columns content \
      --query "fast performance"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search engine based on inverted index",
    #           "These characteristics result in superior [performance] on real-time applications"
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

検出された区切り文字（ `.` と後続の空白）が結果のスニペットに含まれていないことに気づいたでしょうか。これは意図した挙動です。

現在の条件からキーワードを抽出するのではなく、キーワードを明示的に指定することもできます。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                "fast", \
                                "performance", \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]" \
                                })'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, gro",
    #           "onga allows updates without read locks. These characteristics result in superior [performance] on real-time applications."
    #         ]
    #       ],
    #       [
    #         null
    #       ]
    #     ]
    #   ]
    # ]

この `snippet` は最初のレコードでは2つのスニペットを返し、2番目のレコードでは `null` を返しています。なぜなら2番目のレコードには指定したキーワードが含まれていないからです。

キーワードごとに開始タグと終了タグを指定することができます。

実行例:

    select Documents \
      --output_columns 'snippet(content, \
                                "fast", "[", "]", \
                                "performance", "(", ")")'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "snippet",
    #           null
    #         ]
    #       ],
    #       [
    #         [
    #           "Groonga is a [fast] and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, gro",
    #           "onga allows updates without read locks. These characteristics result in superior (performance) on real-time applications."
    #         ]
    #       ],
    #       [
    #         null
    #       ]
    #     ]
    #   ]
    # ]

この `snippet` は `fast` を `[` と `]]` で囲み、 `performance` を `(` と `)` で囲みます。

TODO: `html_escape` option and so on

## 7.15.20.4. 引数

### 7.15.20.4.1. 必須引数

TODO

### 7.15.20.4.2. 省略可能引数

TODO

#### 7.15.20.4.2.1. `max_n_results`

TODO

#### 7.15.20.4.2.2. `width`

TODO

## 7.15.20.5. 戻り値

この関数は文字列の配列もしくは `null` を返します。この関数はは該当するスニペットがない場合に `null` を返します。

配列の要素がスニペットになります:

    [SNIPPET1, SNIPPET2, ...]

スニペットには1つ以上のキーワードが含まれています。開始タグと終了タグを除いたスニペットの最大サイズは200byteです。単位は文字数ではなくてバイトです。

これは width オプションで変更できます。

配列のサイズは1以上3以下です。

この値は max_n_results オプションで変更できます。

## 7.15.20.6. 参考

- snippet_html

- select