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

- English page

### ナビゲーション

- 索引
- 次へ |
- 前へ |
- groonga v2.0.2ドキュメント »
- 7. リファレンスマニュアル »
- 7.3. コマンド »

# 7.3.17. select

## 7.3.17.1. 概要

`select` はテーブルから指定された条件にマッチするレコードを検索し、見つかったレコードを出力します。

`select` は最も重要なgroongaのコマンドです。groongaの力を最大限に活かすためには `select` を理解する必要があります。

## 7.3.17.2. 構文

`select` には多くの引数があります。必須の引数は `table` だけで、残りは省略できます。:

    select table
           [match_columns=null]
           [query=null]
           [filter=null]
           [scorer=null]
           [sortby=null]
           [output_columns="_id, _key, *"]
           [offset=0]
           [limit=10]
           [drilldown=null]
           [drilldown_sortby=null]
           [drilldown_output_columns=null]
           [drilldown_offset=0]
           [drilldown_limit=10]
           [cache=yes]
           [match_escalation_threshold=0]
           [query_expansion=null]

## 7.3.17.3. 使い方

例を使いながら `select` の使い方を学びましょう。このセクションではよく使われる使い方を紹介します。

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

実行例:

    table_create Entries TABLE_HASH_KEY ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Entries content COLUMN_SCALAR Text
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Entries n_likes COLUMN_SCALAR UInt32
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    table_create Terms TABLE_PAT_KEY|KEY_NORMALIZE ShortText --default_tokenizer TokenBigram
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Terms entries_key_index COLUMN_INDEX|WITH_POSITION Entries _key
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Terms entries_content_index COLUMN_INDEX|WITH_POSITION Entries content
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Entries
    [
    {"_key":    "The first post!",
     "content": "Welcome! This is my first post!",
     "n_likes": 5},
    {"_key":    "Groonga",
     "content": "I started to use groonga. It's very fast!",
     "n_likes": 10},
    {"_key":    "Mroonga",
     "content": "I also started to use mroonga. It's also very fast! Really fast!",
     "n_likes": 15},
    {"_key":    "Good-bye Senna",
     "content": "I migrated all Senna system!",
     "n_likes": 3},
    {"_key":    "Good-bye Tritonn",
     "content": "I also migrated all Tritonn system!",
     "n_likes": 3}
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 5]

ブログエントリ用の `Entries` テーブルがあります。各エントリはタイトルと内容と「いいね！」数を持っています。タイトルは `Entries` のキーとします。内容は `Entries.content` カラムの値とします。「いいね！」数は `Entries.n_likes` カラムの値とします。

`Entries._key` カラムと `Entries.content` カラムには `TokenBigram` トークナイザーを使ったインデックスを作成します。そのため、 `Entries._key` と `Entries.content` は両方とも全文検索できます。

これで例を示すためのスキーマとデータの準備ができました。

### 7.3.17.3.1. 簡単な使い方

上記のスキーマとデータを使った一番簡単な使い方を示します。この例では `Entries` テーブルのすべてのレコードを出力します。

実行例:

    select Entries
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

どうしてこのコマンドがすべてのレコードを出力するのでしょうか？理由は2つです。1つ目の理由はこのコマンドが検索条件を何も指定していないからです。検索条件を指定しないとすべてのレコードがマッチします。2つ目の理由は全レコード数が5だからです。 `select` コマンドはデフォルトでは最大10レコードを出力します。この例では5レコードしかありません。これは10よりも少ないのですべてのレコードを出力します。

### 7.3.17.3.2. 検索条件

検索条件は `query` または `filter` で指定します。 `query` と `filter` を両方指定することもできます。この場合は `query` と `filter` の両方の条件にマッチしたレコードが出力されます。

#### 7.3.17.3.2.1. 検索条件: `query`

`query` はWebページの検索ボックス用に用意されています。例えば、google.co.jpにあるような検索ボックスです。 `query` の検索条件はスペース区切りでキーワードを指定します。例えば、 `検索 エンジン` は `検索` と `エンジン` という2つのキーワードを含むレコードを検索します。

通常は `query` 引数は全文検索条件を指定するために使います。全文検索条件以外も指定できますが、その用途には `filter` 引数の方が向いています。

`query` 引数で全文検索条件を指定する場合は、 `match_columns` 引数と一緒に使います。 `match_columns` はどのカラムまたはインデックスを使って `query` を検索するかを指定します。

以下は簡単な `query` の使用例です。

実行例:

    select Entries --match_columns content --query fast
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `content` カラムの値に `fast` を含んでいるレコードを検索します。

`query` はクエリ構文という構文を使いますが、詳細はここでは説明しません。詳細は クエリ構文 を参照してください。

#### 7.3.17.3.2.2. 検索条件: `filter`

`filter` は複雑な検索条件を指定するために用意されています。ECMAScriptのような構文で `filter` に検索条件を指定します。

以下は簡単な `filter` の使用例です。

実行例:

    select Entries --filter 'content @ "fast" && _key == "Groonga"'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中の `content` カラムの値に `fast` という単語を含んでいて、かつ、 `_key` が `Groonga` のレコードを検索します。このコマンドの中には `@` と `&&` と `==` という3つの演算子があります。 `@` は全文検索用の演算子です。 `&&` と `==` はECMAScriptと同じ意味です。 `&&` が論理積用の演算子で `==` が等価演算子です。

`filter` にはもっと演算子や構文があります。例えば、 `(...)` を使った検索条件のグループ化などです。しかし、ここでは詳細は説明しません。詳細は スクリプト構文 を参照してください。

### 7.3.17.3.3. ページング

`offset` と `limit` を指定することで出力されるレコードの範囲を指定できます。以下は2番目のレコードだけを出力する例です。

実行例:

    select Entries --offset 1 --limit 1
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]

`offset` は0基点です。 `--offset 1` は2番目以降のレコードを出力するという意味になります。

`limit` は出力レコード数の最大値を指定します。 `--limit 1` は多くても1レコードを出力するという意味になります。もし、1つもレコードがマッチしていなければ `select` コマンドはどのレコードも出力しません。

### 7.3.17.3.4. 全レコード数

`--limit 0` を使うとレコードの内容は取得せずに全レコード数だけを取得できます。

実行例:

    select Entries --limit 0
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

`--limit 0` はマッチしたレコード数だけを取得したいときにも便利です。

## 7.3.17.4. 引数

このセクションではすべての引数について説明します。引数はカテゴリわけしています。

### 7.3.17.4.1. 必須引数

`table` だけが必須の引数です。

#### 7.3.17.4.1.1. `table`

検索対象のテーブルを指定します。 `table` は必ず指定しなければいけません。

存在しないテーブルを指定するとエラーが返ります。

実行例:

    select Nonexistent
    # [
    #   [
    #     -22,
    #     1337566253.89858,
    #     0.000355720520019531,
    #     "invalid table name: <Nonexistent>",
    #     [
    #       [
    #         "grn_select",
    #         "proc.c",
    #         542
    #       ]
    #     ]
    #   ]
    # ]

### 7.3.17.4.2. 検索関係の引数

検索関係の引数がいくつかあります。一般的には、検索ボックスを実装するために `match_columns` と `query` 引数を使い、複雑な検索機能を実装するために `filter` 引数を使います。

`query` と `filter` を指定した場合は、 `query` と `filter` にマッチしたレコードが選択されます。 `query` と `filter` のどちらも指定しなかった場合はすべてのレコードが選択されます。

#### 7.3.17.4.2.1. `match_columns`

`query` 引数の値で全文検索をするときに使うデフォルトの検索対象カラムを指定します。全文検索対象のカラムは `query` 引数でも指定できます。検索対象カラムを `match_columns` で指定する場合と `query` で指定する場合の違いは重みを指定できるかどうかです。 `match_columns` では重みを指定できますが、 `query` では指定できません。

重みは検索対象カラムの相対的な重要度です。重みの大きい検索対象カラムでマッチした場合は小さい検索対象カラムでマッチした場合よりも多くのヒットスコアがつきます。デフォルトの重みは1です。

以下は簡単な `match_columns` の使用例です。

実行例:

    select Entries --match_columns content --query fast --output_columns '_key, _score'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "Groonga",
    #         1
    #       ],
    #       [
    #         "Mroonga",
    #         2
    #       ]
    #     ]
    #   ]
    # ]

`--match_columns content` はデフォルトの全文検索対象カラムに `content` カラムを使用し、その重みは1、という意味になります。 `--output_columns '_key, _score'` はこの `select` コマンドがマッチしたレコードの `_key` の値と `_score` の値を出力する、ということを指定しています。

`_score` の値に注目してください。 `_score` の値は `query` 引数の値に何個マッチしたかになっています。この例では、 `query` 引数の値は `fast` です。 `_score` の値が1ということは `content` カラムの中に `fast` が1つだけあるということです。 `_score` の値が2ということは `content` カラムの中に `fast` が2つあるということです。

重みを指定するためには `column * weight` という構文を使います。以下は重みの使用例です。

実行例:

    select Entries --match_columns 'content * 2' --query fast --output_columns '_key, _score'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "Groonga",
    #         2
    #       ],
    #       [
    #         "Mroonga",
    #         4
    #       ]
    #     ]
    #   ]
    # ]

`--match_columns 'content * 2'` はデフォルトの全文検索用カラムとして `content` カラムを使い、その重みは2という意味です。

`_score` の値に注目してください。 `_score` の値が2倍になっています。これは重みを2にしたからです。

デフォルトの全文検索対象カラムとして複数のカラムを指定することができます。複数のカラムを指定した場合はすべてのカラムに対して全文検索が行われ、ヒットスコアが積算されます。つまり、 `query` 引数の値がどれか1つでも全文検索対象カラムにマッチしたら、そのレコードはマッチしたものとして扱われます。

複数のカラムを指定するには `column1 * weight1 || column2 * weight2 || ...` という構文を使います。 `* weight` は省略することができます。省略した場合は重みが1になります。以下は複数カラムの使用例です。

実行例:

    select Entries --match_columns '_key * 10 || content' --query groonga --output_columns '_key, _score'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "Groonga",
    #         11
    #       ]
    #     ]
    #   ]
    # ]

`--match_columns '_key * 10 || content'` はデフォルト検索対象カラムが `_key` カラムと `content` カラムで、 `_key` カラムの重みは10、 `content` カラムの重みは1という意味です。この重み付けは `_key` カラムの値は `content` カラムの値よりも重要だという意味になります。この例では、ブログエントリのタイトルはブログエントリの内容よりも重要だということです。

#### 7.3.17.4.2.2. `query`

クエリテキストを指定します。通常、全文検索をするために `match_columns` 引数と一緒に使います。 `query` 引数はWebページにある全文検索フォームで使いやすいように設計されています。クエリテキストは クエリ構文 という書式を使います。この書式はGoogleの検索フォームのように一般的な検索フォームと似ています。例えば、 `word1 word2` は `word1` と `word2` を含んでいるレコードを検索するという意味になります。 `word1 OR word2` は `word1` または `word2` を含んでいるレコードを検索するという意味になります。

以下は論理積を使った検索の簡単な例です。

実行例:

    select Entries --match_columns content --query "fast groonga"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `content` カラムの値に `fast` と `groonga` の2つの単語を含んでいるレコードを検索します。

以下は論理和を使った検索の簡単な例です。

実行例:

    select Entries --match_columns content --query "groonga OR mroonga"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `content` カラムの値に `fast` または `groonga` のどちらかの単語を含んでいるレコードを検索します。

他の構文は クエリ構文 を参照してください。

`query` では全文検索だけではなく他の条件も使えます。例えば、 `column:value` は `column` の値が `value` と等しいという意味です。 `column:<value` は `column` の値が `value` より小さいという意味です。

以下は等価演算子を使った検索の簡単な例です。

実行例:

    select Entries --query _key:Groonga
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `_key` カラムの値が `Groonga` であるレコードを検索します。

以下は比較演算子を使った検索の簡単な例です。

実行例:

    select Entries --query n_likes:<11
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         4
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `n_likes` カラムの値が `11` より小さいレコードを検索します。

他の演算子は クエリ構文 を参照してください。

#### 7.3.17.4.2.3. `filter`

フィルターテキストを指定します。通常、 `filter` は複雑な条件を指定するために使います。 `filter` は `query` 引数と一緒に使うこともできます。 `filter` と `query` を両方指定した場合はそれらを論理積で組み合わせます。つまり、マッチするレコードは `filter` にも `query` にもマッチしなければいけないということです。

`filter` 引数は複雑な条件用に設計されています。フィルターテキストは スクリプト構文 書式で指定します。この書式はECMAScriptに似ています。例えば、 `column == "value"` は `column` カラムの値が `"value"` と等しいという意味です。 `column < value` は `column` カラムの値が `value` よりも小さいという意味です。

以下は等価演算子を使った検索の簡単な例です。

実行例:

    select Entries --filter '_key == "Groonga"'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `_key` カラムの値が `Groonga` であるレコードを検索します。

以下は比較演算子を使った検索の簡単な例です。

実行例:

    select Entries --filter 'n_likes < 11'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         4
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `Entries` テーブルの中から `n_likes` カラムの値が `11` より小さいレコードを検索します。

他の演算子は スクリプト構文 を参照してください。

### 7.3.17.4.3. 高度な検索のための引数

#### 7.3.17.4.3.1. `match_escalation_threshold`

検索方法をエスカレーションするかどうかを決定するための閾値を指定します。この閾値はマッチしたレコード数との比較に使われます。マッチしたレコード数がこの閾値以下の場合は検索方法をエスカレーションします。検索方法のエスカレーションについては 検索 を参照してください。

デフォルトの閾値は0です。これは1つもレコードがマッチしなかったときだけ検索方法をエスカレーションするということです。

デフォルトの閾値は以下の方法でカスタマイズできます。

> - configureの `--with-match-escalation-threshold` オプション
> - groongaコマンドの `--match-escalation-threshold` オプション
> - 設定ファイルの `match-escalation-threshold` 設定項目

以下は簡単な `match_escalation_threshold` の使用例です。最初の `select` は `match_escalation_threshold` 引数がありません。2番目の `select` は `match_escalation_threshold` 引数があります。

実行例:

    select Entries --match_columns content --query groo
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ]
    #     ]
    #   ]
    # ]
    select Entries --match_columns content --query groo --match_escalation_threshold -1
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         0
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ]
    #     ]
    #   ]
    # ]

最初の `select` コマンドは `Entries` テーブルから `content` カラムの値に `groo` という単語を含むレコードを検索します。しかし、 `TokenBigram` トークナイザーは `groonga` を `gr|ro|oo|on|ng|ga` ではなく `groonga` とトークナイズするため、1つもマッチしません。（ `TokenBigramSplitSymbolAlpha` トークナイザーは `groonga` を `gr|ro|oo|on|ng|ga` とトークナイズします。詳細は Tokenizers を参照してください。）これは、 `groonga` はインデックスされていますが、 `groo` はインデックスされていないということです。この場合、マッチしたレコード数（0）が `match_escalation_threshold` （0）と等しいので、検索方法をエスカレーションします。非わかち書き検索を行うと `groo` でレコードが1つマッチします。

2番目の `select` コマンドも `Entries` テーブルから `content` カラムの値に `groo` という単語を含むレコードを検索します。そして、この `select` コマンドもマッチしません。この場合、マッチしたレコード数（0）が `match_escalation_threshold` （-1）より大きいので、検索方法をエスカレーションしません。そして、1つもレコードがマッチしません。

#### 7.3.17.4.3.2. `query_expansion`

クエリ展開用の引数です。クエリ展開はクエリ中の特定の単語を別の単語に置換します。通常は類義語検索に使います。

`query` 引数の値を置換するために使うカラムを指定します。この引数の値の書式は「 `${TABLE}.${COLUMN}` 」です。例えば、 「 `Terms.synonym` 」は `Terms` テーブルの `synonym` カラムを指定しています。

クエリ展開用のテーブルを「置換テーブル」と呼びます。置換テーブルのキーは `ShortText` にしてください。そのため、配列テーブル（ `TABLE_NO_KEY` ）は置換テーブルに使うことはできません。なぜなら、配列テーブルにはキーがないからです。

クエリ展開用のカラムを「置換カラム」と呼びます。置換カラムの値の型は `ShortText` にしてください。カラムの種類はベクター（ `COLUMN_VECTOR` ）にしてください。

クエリ展開はクエリの中にある置換テーブルのキーを置換カラムの値で置換します。 `query` の中にある単語が置換テーブルのキーだったら、キーに対応する置換カラムの値でその単語を置換します。置換は再帰的に実行しません。これは、置換されたクエリ内に置換対象の単語があっても置換されないということです。

以下は `query_expansion` の簡単な使用例を示すためのサンプル置換テーブルです。

実行例:

    table_create Thesaurus TABLE_PAT_KEY|KEY_NORMALIZE ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Thesaurus synonym COLUMN_VECTOR ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Thesaurus
    [
    {"_key": "mroonga", "synonym": ["mroonga", "tritonn", "groonga mysql"]},
    {"_key": "groonga", "synonym": ["groonga", "senna"]}
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 2]

`Thesaurus` 置換テーブルは2つの類義語があります。 `"mroonga"` と `"groonga"` です。ユーザが `"mroonga"` で検索すると、groongaは `"((mroonga) OR (tritonn) OR (groonga mysql))"` で検索します。ユーザーが `"groonga"` で検索すると、groongaは `"((groonga) OR (senna))"` で検索します。通常、置換テーブルには `KEY_NORMALIZE` フラグをつけた方がよいです。このフラグを使うと、置換対象の単語が大文字小文字区別せずにマッチするようになります。

これらの類義語の値の中に `"mroonga"` や `"groonga"` といったキーの値も含まれていることに注意してください。このように類義語にキーの値も含めることを推奨します。もしキーの値を含めないと、置換した値には元の置換対象の値が含まれません。通常、元の値が含まれていた方がよい検索結果になります。もし、検索してほしくない単語がある場合は、元の単語を含めないでください。例えば、空のベクター値を指定することで「ストップワード」機能を実現することもできます。

以下は簡単な `query_expansion` の使用例です。

実行例:

    select Entries --match_columns content --query "mroonga"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         1
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ]
    #     ]
    #   ]
    # ]
    select Entries --match_columns content --query "mroonga" --query_expansion Thesaurus.synonym
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]
    select Entries --match_columns content --query "((mroonga) OR (tritonn) OR (groonga mysql))"
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

最初の `select` コマンドはクエリ展開を使いません。そのため、 `"tritonn"` という単語を含んでいるレコードは見つかりません。2番目の `select` コマンドはクエリ展開を使っています。そのため、 `"tritonn"` という単語を含んでいるレコードが見つかります。3番目の `select` コマンドはクエリ展開を使っていませんが、2番目の `select` コマンドと同じ結果になります。これは、3番目の `select` コマンドは展開後のクエリを使っているからです。

それぞれの置換する値は `(...)` や `OR` といった クエリ構文 を使えます。これらの構文を使うことにより複雑な置換をすることができます。

以下はクエリ構文を使った複雑な置換の使用例です。

実行例:

    load --table Thesaurus
    [
    {"_key": "popular", "synonym": ["popular", "n_likes:>=10"]}
    ]
    # [[0, 1337566253.89858, 0.000355720520019531], 1]
    select Entries --match_columns content --query "popular" --query_expansion Thesaurus.synonym
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ]
    #     ]
    #   ]
    # ]

この `load` コマンドは新しく `"popular"` という類義語を登録しています。これは `((popular) OR (n_likes:>=10))` に置換されます。置換されたクエリは、「popular」というのは「popular」という単語を含んでいるか10以上の「いいね！」数を持つエントリという意味になります。

この `select` コマンドは `Entries` テーブルの中から `n_likes` カラムの値が `10` 以上のレコードを出力します。

### 7.3.17.4.4. 出力関連の引数

#### 7.3.17.4.4.1. `output_columns`

出力するカラムを `,` 区切りで指定します。

以下は簡単な `output_columns` の使用例です。

実行例:

    select Entries --output_columns '_id, _key' --limit 1
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         1,
    #         "The first post!"
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `_id` と `_key` カラムの値だけを出力します。

`*` は特別な値です。 疑似カラム (pseudo_column) 以外のすべてのカラムという意味です。

以下は `*` の使用例です。

実行例:

    select Entries --output_columns '_key, *' --limit 1
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `_key` 擬似カラム、 `content` カラム、 `n_likes` カラムの値を出力しますが、 `_id` 擬似カラムの値は出力しません。

デフォルト値は `_id, _key, *` です。これは `_score` 以外の全てのカラムを出力するという意味です。

#### 7.3.17.4.4.2. `sortby`

ソートキーを `,` 区切りで指定します。それぞれのソートキーはカラム名を指定します。

以下は簡単な `sortby` の使用例です。

実行例:

    select Entries --sortby 'n_likes, _id'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `n_likes` カラムの値で昇順にソートします。 `n_likes` の値が同じレコードについては `_id` カラムの値で昇順にソートします。 `"Good-bye Senna"` と `"Good-bye Tritonn"` が `_id` カラムの値でソートしているケースです。

降順でソートしたい場合はカラム名の前に `-` をつけてください。

以下は降順の `sortby` の使用例です。

実行例:

    select Entries --sortby '-n_likes, _id'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは `n_likes` カラムの値で降順にソートします。しかし、 `_id` でソートするときは昇順でソートします。

もし、 `query` または `filter` 引数を使っているときは、 `sortby` の中で `_score` 擬似カラムを使うことができます。

実行例:

    select Entries --match_columns content --query fast --sortby -_score --output_columns '_key, _score'
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         2
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "_score",
    #           "Int32"
    #         ]
    #       ],
    #       [
    #         "Mroonga",
    #         2
    #       ],
    #       [
    #         "Groonga",
    #         1
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドはマッチしたレコードをヒットスコアで降順にソートし、レコードのキーとヒットスコアを出力します。

`query` 引数も `filter` 引数も指定しないで `_score` を使った場合は、 `_score` を無視して、ログファイルに警告を出力します。

#### 7.3.17.4.4.3. `offset`

出力するレコードの範囲を決めるためのオフセットを指定します。オフセットは0基点です。 `--offset 1` は2番目以降のレコードを出力するという意味になります。

実行例:

    select Entries --sortby _id --offset 3 --output_columns _key
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "Good-bye Senna"
    #       ],
    #       [
    #         "Good-bye Tritonn"
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは4番目以降のレコードを出力します。

負の値を指定することもできます。負の値の場合は `マッチしたレコード数 + offset` 番目のレコードから始まる範囲という意味になります。もし、マッチしたレコードが3つあり、 `--offset -2` を指定した場合は1番目（ `3 + -2 = 1` ） のレコードから3番目のレコードが出力されます。

実行例:

    select Entries --sortby _id --offset -2 --output_columns _key
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "Good-bye Senna"
    #       ],
    #       [
    #         "Good-bye Tritonn"
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは4番目以降のレコードを出力します。なぜなら、全レコード数が `5` だからです。

デフォルト値は `0` です。

#### 7.3.17.4.4.4. `limit`

`limit` は出力レコード数の最大値を指定します。 もし、マッチしたレコード数が `limit` よりも小さい場合はすべてのレコードが出力されます。

以下は簡単な `limit` の使用例です。

実行例:

    select Entries --sortby _id --offset 2 --limit 3 --output_columns _key
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_key",
    #           "ShortText"
    #         ]
    #       ],
    #       [
    #         "Mroonga"
    #       ],
    #       [
    #         "Good-bye Senna"
    #       ],
    #       [
    #         "Good-bye Tritonn"
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドは3番目、4番目、5番目のレコードを出力します。

負の値を指定することもできます。負の値の場合は、最大で `マッチしたレコード数 + limit + 1` 件のレコードを出力するという意味になります。 例えば、 `--limit -1` はすべてのレコードを出力します。これはすべてのレコードを表示する場合にとても便利です。

以下は負の値を使った `limit` の簡単な使用例です。

実行例:

    select Entries --limit -1
    # [
    #   [
    #     0,
    #     1337566253.89858,
    #     0.000355720520019531
    #   ],
    #   [
    #     [
    #       [
    #         5
    #       ],
    #       [
    #         [
    #           "_id",
    #           "UInt32"
    #         ],
    #         [
    #           "_key",
    #           "ShortText"
    #         ],
    #         [
    #           "content",
    #           "Text"
    #         ],
    #         [
    #           "n_likes",
    #           "UInt32"
    #         ]
    #       ],
    #       [
    #         1,
    #         "The first post!",
    #         "Welcome! This is my first post!",
    #         5
    #       ],
    #       [
    #         2,
    #         "Groonga",
    #         "I started to use groonga. It's very fast!",
    #         10
    #       ],
    #       [
    #         3,
    #         "Mroonga",
    #         "I also started to use mroonga. It's also very fast! Really fast!",
    #         15
    #       ],
    #       [
    #         4,
    #         "Good-bye Senna",
    #         "I migrated all Senna system!",
    #         3
    #       ],
    #       [
    #         5,
    #         "Good-bye Tritonn",
    #         "I also migrated all Tritonn system!",
    #         3
    #       ]
    #     ]
    #   ]
    # ]

この `select` コマンドはすべてのレコードを出力します。

デフォルト値は `10` です。

#### 7.3.17.4.4.5. `scorer`

TODO: write in English and add example.

検索条件にマッチする全てのレコードに対して適用するgrn_exprをscript形式で指定します。

scorerは、検索処理が完了し、ソート処理が実行される前に呼び出されます。従って、各レコードのスコアを操作する式を指定しておけば、検索結果のソート順序をカスタマイズできるようになります。

### 7.3.17.4.5. ファセット関連の引数

#### 7.3.17.4.5.1. `drilldown`

TODO: write in English and add example.

グループ化のキーとなるカラム名のリストをカンマ(',')区切りで指定します。検索条件にマッチした各レコードを出力したのちに、drilldownに指定されたカラムの値が同一であるレコードをとりまとめて、それぞれについて結果レコードを出力します。

#### 7.3.17.4.5.2. `drilldown_sortby`

TODO: write in English and add example.

drilldown条件に指定されたカラムの値毎にとりまとめられたレコードについて、ソートキーとなるカラム名のリストをカンマ(',')区切りで指定します。sortbyパラメータと同様に昇降順を指定できます。

#### 7.3.17.4.5.3. `drilldown_output_columns`

TODO: write in English and add example.

drilldown条件に指定されたカラムの値毎にとりまとめられたレコードについて、出力するカラム名のリストをカンマ(',')区切りで指定します。

#### 7.3.17.4.5.4. `drilldown_offset`

TODO: write in English and add example.

drilldown条件に指定されたカラムの値毎にとりまとめられたレコードについて、出力対象となる最初のレコードの番号を0ベースで指定します。デフォルト値は0です。drilldown_offsetに負の値を指定した場合は、ヒットした件数 + drilldown_offsetによって算出される値が指定されたものとみなされます。

#### 7.3.17.4.5.5. `drilldown_limit`

TODO: write in English and add example.

drilldown条件に指定されたカラムの値毎にとりまとめられたレコードについて、出力を行うレコードの件数を指定します。デフォルト値は10です。実際には、drilldown_offset + drilldown_limit がヒットした件数を超えない範囲でレコードが出力されます。drilldown_limitに負の値を指定した場合は、ヒットした件数 + drilldown_limit + 1 によって算出される値が指定されたものとみなされます。

### 7.3.17.4.6. キャッシュ関連の引数

#### 7.3.17.4.6.1. `cache`

TODO: write in English and add example.

クエリキャッシュに関する動作を設定します。

`no`

> 検索結果をクエリキャッシュに残しません。キャッシュして再利用される可能性が低いクエリに対して用います。キャッシュ容量は有限です。有効なキャッシュが多くヒットするために、このパラメータは有効です。

## 7.3.17.5. 返値

TODO: write in English and add example.

以下のようなjson形式で値が返却されます。

    [[リターンコード, 処理開始時間, 処理時間], [検索結果, ドリルダウン結果]]

`リターンコード`

> grn_rcに対応する数値が返されます。0(GRN_SUCCESS)以外の場合は、続いてエラー内容を示す 文字列が返されます。

`処理開始時間`

> 処理を開始した時間について、1970年1月1日0時0分0秒を起点とした秒数を小数で返します。

`処理時間`

> 処理にかかった秒数を返します。

`検索結果`

> drilldown条件が実行される前の検索結果が以下のように出力されます。:

>     [[検索件数], [[カラム名1,カラム型1],..], 検索結果1,..]

> `検索件数`

> > 検索件数が出力されます。

> `カラム名n`

> > output_columnsに指定された条件に従って、対象となるカラム名が出力されます。

> `カラム型n`

> > output_columnsに指定された条件に従って、対象となるカラム型が出力されます。

> `検索結果n`

> > output_columns, offset, limitによって指定された条件に従って各レコードの値が出力されます。

`drilldown結果`

> drilldown処理の結果が以下のように出力されます。:

>     [[[件数], [[カラム名1,カラム型1],..], 検索結果1,..],..]

> `件数`

> > drilldownに指定されたカラムの値の異なり数が出力されます。

> `カラム名n`

> > drilldown_output_columnsに指定された条件に従って、対象となるカラム名が出力されます。

> `カラム型n`

> > drilldown_output_columnsに指定された条件に従って、対象となるカラム型が出力されます。

> `ドリルダウン結果n`

> > drilldown_output_columns, drilldown_offset, drilldown_limitによって指定された条件に従って各レコードの値が出力されます。

## 7.3.17.6. 参考

> - クエリ構文
> - スクリプト構文

### ナビゲーション

- 索引
- 次へ |
- 前へ |
- groonga v2.0.2ドキュメント »
- 7. リファレンスマニュアル »
- 7.3. コマンド »