7.3.54. select
¶
7.3.54.1. 概要¶
select
はテーブルから指定された条件にマッチするレコードを検索し、見つかったレコードを出力します。
select
は最も重要なgroongaのコマンドです。Groongaの力を最大限に活かすためには select
を理解する必要があります。
7.3.54.2. 構文¶
このコマンドにはたくさんの引数があります。
必須の引数は 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="_key, _nsubrecs"]
[drilldown_offset=0]
[drilldown_limit=10]
[cache=yes]
[match_escalation_threshold=0]
[query_expansion=null]
[query_flags=ALLOW_PRAGMA|ALLOW_COLUMN]
[query_expander=null]
[adjuster=null]
[drilldown_calc_types=NONE]
[drilldown_calc_target=null]
[drilldown_filter=null]
[sort_keys=null]
[drilldown_sort_keys=null]
This command has the following named parameters for dynamic columns:
columns[${NAME}].stage=null
columns[${NAME}].flags=COLUMN_SCALAR
columns[${NAME}].type=null
columns[${NAME}].value=null
columns[${NAME}].window.sort_keys=null
columns[${NAME}].window.group_keys=null
You can use one or more alphabets, digits, _
for ${NAME}
. For
example, column1
is a valid ${NAME}
. This is the same rule as
normal column. See also name.
Parameters that have the same ${NAME}
are grouped.
For example, the following parameters specify one dynamic column:
--columns[name].stage initial
--columns[name].type UInt32
--columns[name].value 29
The following parameters specify two dynamic columns:
--columns[name1].stage initial
--columns[name1].type UInt32
--columns[name1].value 29
--columns[name2].stage filtered
--columns[name2].type Float
--columns[name2].value '_score * 0.1'
This command has the following named parameters for advanced drilldown:
drilldowns[${LABEL}].keys=null
drilldowns[${LABEL}].sort_keys=null
drilldowns[${LABEL}].output_columns="_key, _nsubrecs"
drilldowns[${LABEL}].offset=0
drilldowns[${LABEL}].limit=10
drilldowns[${LABEL}].calc_types=NONE
drilldowns[${LABEL}].calc_target=null
drilldowns[${LABEL}].filter=null
drilldowns[${LABEL}].columns[${NAME}].stage=null
drilldowns[${LABEL}].columns[${NAME}].flags=COLUMN_SCALAR
drilldowns[${LABEL}].columns[${NAME}].type=null
drilldowns[${LABEL}].columns[${NAME}].value=null
drilldowns[${LABEL}].columns[${NAME}].window.sort_keys=null
drilldowns[${LABEL}].columns[${NAME}].window.group_keys=null
バージョン 6.0.3 で撤廃: drilldown[...]
構文は非推奨になりました。代わりに drilldowns[...]
を使用してください。
${LABEL}
には1つ以上のアルファベット、数字、 _
、 .
を使うことができます。たとえば、 parent.sub1
は有効な ${LABEL}
です。
同じ ${LABEL}
も持つ引数は同じグループになります。
たとえば、以下の引数は1つのドリルダウンを指定しています。
--drilldowns[label].keys column
--drilldowns[label].sort_keys -_nsubrecs
以下の引数は2つのドリルダウンを指定しています。
--drilldowns[label1].keys column1
--drilldowns[label1].sort_keys -_nsubrecs
--drilldowns[label2].keys column2
--drilldowns[label2].sort_keys _key
7.3.54.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]
column_create Entries tag COLUMN_SCALAR ShortText
# [[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 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,
"tag": "Hello"},
{"_key": "Groonga",
"content": "I started to use Groonga. It's very fast!",
"n_likes": 10,
"tag": "Groonga"},
{"_key": "Mroonga",
"content": "I also started to use Mroonga. It's also very fast! Really fast!",
"n_likes": 15,
"tag": "Groonga"},
{"_key": "Good-bye Senna",
"content": "I migrated all Senna system!",
"n_likes": 3,
"tag": "Senna"},
{"_key": "Good-bye Tritonn",
"content": "I also migrated all Tritonn system!",
"n_likes": 3,
"tag": "Senna"}
]
# [[0, 1337566253.89858, 0.000355720520019531], 5]
ブログエントリ用の Entries
テーブルがあります。各エントリはタイトルと内容と「いいね!」数、タグを持っています。タイトルは Entries
のキーとします。内容は Entries.content
カラムの値とします。「いいね!」数は Entries.n_likes
カラムの値とします。タグは Entries.tag
カラムの値とします。
Entries._key
カラムと Entries.content
カラムには TokenBigram
トークナイザーを使ったインデックスを作成します。そのため、 Entries._key
と Entries.content
は両方とも全文検索できます。
これで例を示すためのスキーマとデータの準備ができました。
7.3.54.3.1. 簡単な使い方¶
上記のスキーマとデータを使った一番簡単な使い方は以下の通りです。これは Entries
テーブルのすべてのレコードを出力します。
実行例:
select Entries
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 5
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 1,
# "The first post!",
# "Welcome! This is my first post!",
# 5,
# "Hello"
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ],
# [
# 4,
# "Good-bye Senna",
# "I migrated all Senna system!",
# 3,
# "Senna"
# ],
# [
# 5,
# "Good-bye Tritonn",
# "I also migrated all Tritonn system!",
# 3,
# "Senna"
# ]
# ]
# ]
# ]
どうしてこのコマンドがすべてのレコードを出力するのでしょうか?理由は2つです。1つ目の理由はこのコマンドが検索条件を何も指定していないからです。検索条件を指定しないとすべてのレコードがマッチします。2つ目の理由は全レコード数が5だからです。 select
コマンドはデフォルトでは最大10レコードを出力します。この例では5レコードしかありません。これは10よりも少ないのですべてのレコードを出力します。
7.3.54.3.2. 検索条件¶
検索条件は query
または filter
で指定します。 query
と filter
を両方指定することもできます。この場合は query
と filter
の両方の条件にマッチしたレコードが出力されます。
7.3.54.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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
この select
コマンドは Entries
テーブルの中から content
カラムの値に fast
を含んでいるレコードを検索します。
query
はクエリー構文という構文を使いますが、詳細はここでは説明しません。詳細は クエリー構文 を参照してください。
7.3.54.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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ]
# ]
# ]
# ]
この select
コマンドは Entries
テーブルの中の content
カラムの値に fast
という単語を含んでいて、かつ、 _key
が Groonga
のレコードを検索します。このコマンドの中には @
と &&
と ==
という3つの演算子があります。 @
は全文検索用の演算子です。 &&
と ==
はECMAScriptと同じ意味です。 &&
が論理積用の演算子で ==
が等価演算子です。
filter
にはもっと演算子や構文があります。例えば、 (...)
を使った検索条件のグループ化などです。しかし、ここでは詳細は説明しません。詳細は スクリプト構文 を参照してください。
7.3.54.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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ]
# ]
# ]
# ]
offset
は0始まりです。 --offset 1
は2番目以降のレコードを出力するという意味になります。
limit
は出力レコード数の最大値を指定します。 --limit 1
は多くても1レコードを出力するという意味になります。もし、1つもレコードがマッチしていなければ select
コマンドはどのレコードも出力しません。
7.3.54.3.4. 全レコード数¶
--limit 0
を使うとレコードの内容は取得せずに全レコード数だけを取得できます。
実行例:
select Entries --limit 0
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 5
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ]
# ]
# ]
# ]
--limit 0
はマッチしたレコード数だけを取得したいときにも便利です。
7.3.54.3.5. ドリルダウン¶
1回の select
で検索結果だけでなく、検索結果をグループ化した結果も一緒に取得できます。SQLでは2回以上 SELECT
を使わなければいけない場合でも、Groongaの場合は1回の select
で実現できます。
Groongaではこの機能を ドリルダウン と呼んでいます。他の検索エンジンでは ファセット検索 とも呼ばれています。
例えば、以下の状況を考えてみましょう。
fast
という単語を含むエントリーを探します。
実行例:
select Entries --filter 'content @ "fast"'
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
--filter 'content @ "fast" && tag == "???"
というように、追加の検索条件として tag
を使いたいとします。しかし、 content @ "fast"
の結果を見るまでは適切なタグはわかりません。
もし、有効なタグそれぞれについてマッチするレコード数がわかれば、その中から適切なタグを選ぶことができます。このような用途のためにドリルダウンを使えます。
実行例:
select Entries --filter 'content @ "fast"' --drilldown tag
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ],
# [
# [
# 1
# ],
# [
# [
# "_key",
# "ShortText"
# ],
# [
# "_nsubrecs",
# "Int32"
# ]
# ],
# [
# "Groonga",
# 2
# ]
# ]
# ]
# ]
--drilldown tag
は「有効なタグ」と「そのタグを持っているレコード数」のペアをリストにして返します。このリストからタグを選ぶと「検索したけどヒット数0」という状況を避けることができます。また、リストの中からレコード数が少ないタグを選べば「検索結果が多すぎる」という状況も避けることができます。
ドリルダウン結果を使うと次のようなUIを作ることができます。
検索結果を絞り込むリンク。(ユーザーはキーボードから検索クエリーを入力する必要がなくなります。単にリンクをクリックすればよいからです。)
多くのECサイトではこのUIを使っています。Amazonのサイドメニューを見てください。
Groongaはグループ化したレコードの数を数えるだけでなく、グループ化したレコードのカラムの値の中から最大値・最小値を見つけたり、合計値を計算したりすることができます。詳細は ドリルダウン関連の引数 を参照してください。
7.3.54.3.6. 動的カラム¶
1回の select
実行中に0個以上のカラムを動的に作ることができます。この機能を使うと計算した値に対してドリルダウンしたりウィンドウ関数と使ったりできます。
以下は計算した値に対してドリルダウンするために動的カラムを使う例です。この例では n_likes_class
という名前のカラムを新しく作っています。 n_likes_class
カラムには Entry.n_likes
の値を分類した値を入れます。この例では Entry.n_likes
カラムの値を 10
刻みで分類し、一番小さい数値をその分類の代表値とします。もし、 Entry.n_likes
の値が 3
や 5
のように 0
から 9
の間の値なら、 n_likes_class
の値(分類した値)は 0
になります。もし、 Entry.n_likes
の値が 10
や 15
のように 10
から 19
の間の値なら、 n_likes_class
の値(分類した値)は 10
になります。
このような分類をするために doc:/reference/functions/number_classify 関数を使えます。 doc:/reference/functions/number_classify 関数を使うためには plugin_register コマンドで functions/number
プラグインを登録する必要があります。
この例では n_likes_class
の値でドリルダウンしています。このドリルダウン結果があるとデータの傾向がわかりやすくなるでしょう。
実行例:
plugin_register functions/number
# [[0, 1337566253.89858, 0.000355720520019531], true]
select \
--table Entries \
--columns[n_likes_class].stage initial \
--columns[n_likes_class].type UInt32 \
--columns[n_likes_class].value 'number_classify(n_likes, 10)' \
--drilldown n_likes_class \
--drilldown_sort_keys _nsubrecs \
--output_columns n_likes,n_likes_class
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 5
# ],
# [
# [
# "n_likes",
# "UInt32"
# ],
# [
# "n_likes_class",
# "UInt32"
# ]
# ],
# [
# 5,
# 0
# ],
# [
# 10,
# 10
# ],
# [
# 15,
# 10
# ],
# [
# 3,
# 0
# ],
# [
# 3,
# 0
# ]
# ],
# [
# [
# 2
# ],
# [
# [
# "_key",
# "UInt32"
# ],
# [
# "_nsubrecs",
# "Int32"
# ]
# ],
# [
# 10,
# 2
# ],
# [
# 0,
# 3
# ]
# ]
# ]
# ]
詳細は 動的カラム関連の引数 を見てください。
7.3.54.3.7. ウィンドウ関数¶
You can compute each record value from values of grouped records. For example, you can compute sums of each group and puts sums to each record. The difference against drilldown is drilldown can compute sums of each group but it puts sums to each group not record.
Here is the result with window function. Each record has sum:
Group No. | Target value | Sum result |
---|---|---|
1 | 5 | 5 |
2 | 10 | 25 |
2 | 15 | 25 |
3 | 3 | 8 |
3 | 5 | 8 |
Here is the result with drilldown. Each group has sum:
Group No. | Target values | Sum result |
---|---|---|
1 | 5 | 5 |
2 | 10, 15 | 25 |
3 | 3, 5 | 8 |
Window function is useful for data analysis.
Here is an example that sums Entries.n_likes
per
Entries.tag
:
実行例:
plugin_register functions/number
# [[0, 1337566253.89858, 0.000355720520019531], true]
select \
--table Entries \
--columns[n_likes_sum_per_tag].stage initial \
--columns[n_likes_sum_per_tag].type UInt32 \
--columns[n_likes_sum_per_tag].value 'window_sum(n_likes)' \
--columns[n_likes_sum_per_tag].window.group_keys tag \
--output_columns tag,n_likes,n_likes_sum_per_tag
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 5
# ],
# [
# [
# "tag",
# "ShortText"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "n_likes_sum_per_tag",
# "UInt32"
# ]
# ],
# [
# "Hello",
# 5,
# 5
# ],
# [
# "Groonga",
# 10,
# 25
# ],
# [
# "Groonga",
# 15,
# 25
# ],
# [
# "Senna",
# 3,
# 6
# ],
# [
# "Senna",
# 3,
# 6
# ]
# ]
# ]
# ]
See Window function related parameters for details.
7.3.54.4. 引数¶
このセクションではすべての引数について説明します。引数はカテゴリわけしています。
7.3.54.4.1. 必須引数¶
table
だけが必須の引数です。
7.3.54.4.1.1. table
¶
検索対象のテーブルを指定します。 table
は必ず指定しなければいけません。
存在しないテーブルを指定するとエラーが返ります。
実行例:
select Nonexistent
# [
# [
# -22,
# 1337566253.89858,
# 0.000355720520019531,
# "[select][table] invalid name: <Nonexistent>",
# [
# [
# "grn_select",
# "proc_select.c",
# 3006
# ]
# ]
# ]
# ]
7.3.54.4.3. 高度な検索のための引数¶
7.3.54.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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ]
# ]
# ]
# ]
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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ]
# ]
# ]
# ]
最初の select
コマンドは Entries
テーブルから content
カラムの値に groo
という単語を含むレコードを検索します。しかし、この検索ではどのレコードにもマッチしません。これは、 TokenBigram
トークナイザーは groonga
を gr|ro|oo|on|ng|ga
ではなく groonga
にトークナイズするからです。( TokenBigramSplitSymbolAlpha
は groonga
を gr|ro|oo|on|ng|ga
にトークナイズします。詳細は トークナイザー を見てください。)つまり、 groonga
はインデックスに登録されていますが、 groo
はインデックスに登録されていないということです。インデックスに登録されていないので完全一致検索では groo
はどのレコードにもマッチしません。このケースでは検索方法のエスカレーションが行われています。なぜならばマッチしたレコード数(0)が match_escalation_threshold
(0)の値と等しいからです。非分かち書き検索では groo
で1つのレコードがマッチします。
2番目の select
コマンドも Entries
テーブルから content
カラムの値に groo
という単語を含むレコードを検索します。そして、この select
コマンドもマッチしません。この場合、マッチしたレコード数(0)が match_escalation_threshold
(-1)より大きいので、検索方法をエスカレーションしません。そして、1つもレコードがマッチしません。
7.3.54.4.3.2. query_expansion
¶
バージョン 3.0.2 で撤廃: 代わりに query_expander を使ってください。
7.3.54.4.3.3. query_flags
¶
query
パラメーターの構文をカスタマイズします。デフォルトでは query
パラメーターでカラムの値を更新することはできません。しかし、 query_flags
に ALLOW_COLUMN|ALLOW_UPDATE
を指定することで query
でカラムの値を更新することができます。
指定可能な値は以下の通りです。
ALLOW_PRAGMA
ALLOW_COLUMN
ALLOW_UPDATE
ALLOW_LEADING_NOT
NONE
ALLOW_PRAGMA
を指定すると query
の先頭でプラグマを指定することができます。この機能はまだ実装されていません。
ALLOW_COLUMN
を指定すると match_columns
で指定していないカラムでも検索できるように成ります。カラムを指定するには COLUMN:...
というような構文を使います。
ALLOW_UPDATE
を指定すると COLUMN:=NEW_VALUE
という構文を使って query
でカラムの値を更新できます。カラム更新用の構文ではカラムを指定する必要があるため、 ALLOW_COLUMN
も一緒に指定する必要があります。
ALLOW_LEADING_NOT
を指定すると -WORD
という構文を使って最初の条件として否定条件を指定できます。このクエリーは WORD
にマッチしないレコードを検索します。最初の条件に否定条件を使ったクエリーは多くの場合重いクエリーになります。これは多くのレコードにマッチするからです。そのため、このフラグはデフォルトでは無効になっています。もし、このフラグを使う場合は重いクエリーとなるということを十分気をつけてください。
NONE
は単に無視されます。フラグを指定しないときに NONE
を使えます。
これらのフラグは ALLOW_COLUMN|ALLOW_UPDATE
のように |
で区切って同時に指定することができます。
デフォルト値は ALLOW_PRAGMA|ALLOW_COLUMN
です。
以下は ALLOW_COLUMN
の使用例です。
実行例:
select Entries --query content:@mroonga --query_flags ALLOW_COLUMN
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
この select
コマンドは Entries
テーブルの中から content
カラムの値に mroonga
を含んでいるレコードを検索します。
以下は ALLOW_UPDATE
の使用例です。
実行例:
table_create Users TABLE_HASH_KEY ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Users age COLUMN_SCALAR UInt32
# [[0, 1337566253.89858, 0.000355720520019531], true]
load --table Users
[
{"_key": "alice", "age": 18},
{"_key": "bob", "age": 20}
]
# [[0, 1337566253.89858, 0.000355720520019531], 2]
select Users --query age:=19 --query_flags ALLOW_COLUMN|ALLOW_UPDATE
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "age",
# "UInt32"
# ]
# ],
# [
# 1,
# "alice",
# 19
# ],
# [
# 2,
# "bob",
# 19
# ]
# ]
# ]
# ]
select Users
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "age",
# "UInt32"
# ]
# ],
# [
# 1,
# "alice",
# 19
# ],
# [
# 2,
# "bob",
# 19
# ]
# ]
# ]
# ]
最初の select
コマンドは全てのレコードの age
カラムの値を 19
にします。二番目の select
コマンドは age
カラムの値を出力します。
以下は ALLOW_LEADING_NOT
の使用例です。
実行例:
select Entries --match_columns content --query -mroonga --query_flags ALLOW_LEADING_NOT
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 4
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 1,
# "The first post!",
# "Welcome! This is my first post!",
# 5,
# "Hello"
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 4,
# "Good-bye Senna",
# "I migrated all Senna system!",
# 3,
# "Senna"
# ],
# [
# 5,
# "Good-bye Tritonn",
# "I also migrated all Tritonn system!",
# 3,
# "Senna"
# ]
# ]
# ]
# ]
この select
コマンドは Entries
テーブルの中から content
カラムの値に mroonga
を含んでいないレコードを検索します。
以下は NONE
の使用例です。
実行例:
select Entries --match_columns content --query 'mroonga OR _key:Groonga' --query_flags NONE
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
この select
コマンドは Entries
テーブルの中から content
カラムの値に mroonga
または _key:Groonga
のどちらかの単語を含んでいるレコードを検索します。 _key:Groonga
が _key
カラムの値が Groonga
という条件にはならないことに注意してください。これは ALLOW_COLUMN
フラグが指定されていないからです。
クエリー構文 も見てください。
7.3.54.4.3.4. query_expander
¶
クエリー展開用の引数です。クエリー展開はクエリー中の特定の単語を別の単語に置換します。通常は類義語検索に使います。
query
引数の値を置換するために使うカラムを指定します。この引数の値の書式は「 ${TABLE}.${COLUMN}
」です。例えば、 「 Terms.synonym
」は Terms
テーブルの synonym
カラムを指定しています。
クエリー展開用のテーブルを「置換テーブル」と呼びます。置換テーブルのキーは ShortText
にしてください。そのため、配列テーブル( TABLE_NO_KEY
)は置換テーブルに使うことはできません。なぜなら、配列テーブルにはキーがないからです。
クエリー展開用のカラムを「置換カラム」と呼びます。置換カラムの値の型は ShortText
にしてください。カラムの種類はベクター( COLUMN_VECTOR
)にしてください。
クエリー展開はクエリーの中にある置換テーブルのキーを置換カラムの値で置換します。 query
の中にある単語が置換テーブルのキーだったら、キーに対応する置換カラムの値でその単語を置換します。置換は再帰的に実行しません。これは、置換されたクエリー内に置換対象の単語があっても置換されないということです。
以下は query_expander
の簡単な使用例を示すためのサンプル置換テーブルです。
実行例:
table_create Thesaurus TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
# [[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))"
で検索します。
通常、置換テーブルにはノーマライザーを指定したほうがよいです。たとえば、ノーマライザーを指定すると、置換対象の単語に対して大文字小文字区別せずにマッチするようになります。利用可能なノーマライザーは ノーマライザー を参照してください。
これらの類義語の値の中に "mroonga"
や "groonga"
といったキーの値も含まれていることに注意してください。このように類義語にキーの値も含めることを推奨します。もしキーの値を含めないと、置換した値には元の置換対象の値が含まれません。通常、元の値が含まれていた方がよい検索結果になります。もし、検索してほしくない単語がある場合は、元の単語を含めないでください。例えば、空のベクター値を指定することで「ストップワード」機能を実現することもできます。
以下は簡単な query_expander
の使用例です。
実行例:
select Entries --match_columns content --query "mroonga"
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 1
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
select Entries --match_columns content --query "mroonga" --query_expander Thesaurus.synonym
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ],
# [
# 5,
# "Good-bye Tritonn",
# "I also migrated all Tritonn system!",
# 3,
# "Senna"
# ]
# ]
# ]
# ]
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"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ],
# [
# 5,
# "Good-bye Tritonn",
# "I also migrated all Tritonn system!",
# 3,
# "Senna"
# ]
# ]
# ]
# ]
最初の 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_expander Thesaurus.synonym
# [
# [
# 0,
# 1337566253.89858,
# 0.000355720520019531
# ],
# [
# [
# [
# 2
# ],
# [
# [
# "_id",
# "UInt32"
# ],
# [
# "_key",
# "ShortText"
# ],
# [
# "content",
# "Text"
# ],
# [
# "n_likes",
# "UInt32"
# ],
# [
# "tag",
# "ShortText"
# ]
# ],
# [
# 2,
# "Groonga",
# "I started to use Groonga. It's very fast!",
# 10,
# "Groonga"
# ],
# [
# 3,
# "Mroonga",
# "I also started to use Mroonga. It's also very fast! Really fast!",
# 15,
# "Groonga"
# ]
# ]
# ]
# ]
この load
コマンドは新しく "popular"
という類義語を登録しています。これは ((popular) OR (n_likes:>=10))
に置換されます。置換されたクエリーは、「popular」というのは「popular」という単語を含んでいるか10以上の「いいね!」数を持つエントリという意味になります。
この select
コマンドは Entries
テーブルの中から n_likes
カラムの値が 10
以上のレコードを出力します。
7.3.54.5. 戻り値¶
select
は以下のフォーマットのレスポンスを返します:
[
HEADER,
[
SEARCH_RESULT,
DRILLDOWN_RESULT_1,
DRILLDOWN_RESULT_2,
...,
DRILLDOWN_RESULT_N
]
]
select
が失敗すると、 HEADER
にエラーの詳細が含まれます。
HEADER
については 出力形式 を参照してください。
0個以上の DRILLDOWN_RESULT
があります。もし、 drilldown
も drilldowns[${LABEL}].keys
も指定していない場合、次のように DRILLDOWN_RESULT
は出力されません:
[
HEADER,
[
SEARCH_RESULT
]
]
--drilldown "_key, column1, column2"
というように drilldown
に2つ以上のキーがある場合、複数の DRILLDOWN_RESULT
が存在します:
[
HEADER,
[
SEARCH_RESULT,
DRILLDOWN_RESULT_FOR_KEY,
DRILLDOWN_RESULT_FOR_COLUMN1,
DRILLDOWN_RESULT_FOR_COLUMN2
]
]
もし drilldowns[${LABEL}].keys
を使っているなら、 DRILLDOWN_RESULT
が1つだけ存在します:
[
HEADER,
[
SEARCH_RESULT,
DRILLDOWN_RESULT_FOR_LABELED_DRILLDOWN
]
]
DRILLDOWN_RESULT
のフォーマットは drilldown
と drilldowns[${LABEL}].keys
で違います。これについては後述します。
SEARCH_RESULT
は以下のフォーマットです:
[
[N_HITS],
COLUMNS,
RECORDS
]
このフォーマットの具体例は 簡単な使い方 を見てください。
N_HITS
は limit を適用する前のマッチしたレコード数です。
COLUMNS
は output_columns で指定した出力カラムの情報を表しています。これは次のフォーマットになっています:
[
[COLUMN_NAME_1, COLUMN_TYPE_1],
[COLUMN_NAME_2, COLUMN_TYPE_2],
...,
[COLUMN_NAME_N, COLUMN_TYPE_N]
]
COLUMNS
は1つ以上の出力カラムの情報を含んでいます。各出力カラムの情報は次の情報を含んでいます。
カラム名(文字列)
カラムの型(文字列または
null
)
カラム名は output_columns で指定された値から抽出しています。
カラムの方はGroongaでの型名または null
です。カラムがベクターかスカラーかの情報は持っていません。実際のカラムの値が配列かどうかで判断する必要があります。
型の詳細は データ型 を見てください。
null
になるときはカラムの値の型を決められないときです。たとえば、 --output_columns "snippet_html(content)"
というように output_columns の中で関数呼び出しを使ったときは null
になります。
以下は COLUMNS
の使用例です:
[
["_id", "UInt32"],
["_key", "ShortText"],
["n_likes", "UInt32"],
]
RECORDS
はマッチした各レコードのカラムの値を含んでいます。 RECORDS
に含まれるレコードは offset と limit で選択されたレコードです。 RECORDS
は次のフォーマットです:
[
[
RECORD_1_COLUMN_1,
RECORD_1_COLUMN_2,
...,
RECORD_1_COLUMN_N
],
[
RECORD_2_COLUMN_1,
RECORD_2_COLUMN_2,
...,
RECORD_2_COLUMN_N
],
...
[
RECORD_N_COLUMN_1,
RECORD_N_COLUMN_2,
...,
RECORD_N_COLUMN_N
]
]
以下は RECORDS
の例です:
[
[
1,
"The first post!",
5
],
[
2,
"Groonga",
10
],
[
3,
"Mroonga",
15
]
]
DRILLDOWN_RESULT
のフォーマットは drilldown
と drilldowns[${LABEL}].keys
で違います。
drilldown
は SEARCH_RESULT
と同じフォーマットです:
[
[N_HITS],
COLUMNS,
RECORDS
]
drilldown で1つ以上のキーを指定すると、 drilldown
は1つ以上の DRILLDOWN_RESULT
を出力します。
drilldowns[${LABEL}].keys
は次のフォーマットを使います。複数の drilldowns[${LABEL}].keys
は1つのオブジェクト(キーと値のペアの集合)になります:
{
"LABEL_1": [
[N_HITS],
COLUMNS,
RECORDS
],
"LABEL_2": [
[N_HITS],
COLUMNS,
RECORDS
],
...,
"LABEL_N": [
[N_HITS],
COLUMNS,
RECORDS
]
}
各 drilldowns[${LABEL}].keys
は次の部分に対応します:
"LABEL": [
[N_HITS],
COLUMNS,
RECORDS
]
以下の値の部分は SEARCH_RESULT
と同じフォーマットです:
[
[N_HITS],
COLUMNS,
RECORDS
]
drilldownss[${LABEL}]
スタイルのドリルダウンの出力形式については drilldowns[${LABEL}] スタイルの出力フォーマット も見てください。