7.12.2. スクリプト構文

スクリプト構文は複雑な検索条件を指定するための構文です。この構文はECMAScriptに似ています。例えば、 _key == "book"_key の値が "book" のレコードを検索するという意味です。 クエリー構文 ではすべての値は文字列でしたが、スクリプト構文では値に型があります。例えば、 "book" は文字列で 1 は整数で、 TokenBigramTokenBigram という名前のオブジェクトです。

スクリプト構文はECMAScriptの構文と完全に互換性があるわけではありません。例えば、 if 制御文や for 繰り返し文や変数定義文といった文をサポートしていません。関数定義もサポートしていません。しかし、独自の演算子を追加しています。独自の演算子はECMAScriptの構文を説明した後に説明します。

7.12.2.1. セキュリティー

セキュリティーの観点からユーザーからの入力をそのままGroongaに渡すべきではありません。悪意のあるユーザーがそのユーザーには参照できてはいけないレコードを取得するクエリーを入力するかもしれないからです。

例えば、以下の状況を考えてみましょう。

あるGroongaアプリケーションがGroongaへのリクエストを次のようなプログラムで構築していたとします。:

filter = "column @ \"#{user_input}\""
select_options = {
  # ...
  :filter => filter,
}
groonga_client.select(select_options)

user_input はユーザーからの入力です。入力が query だった場合は構築された filter 引数は次のようになります。:

column @ "query"

もし、入力が x" || true || " だった場合は構築された filter 引数は次のようになります。:

column @ "x" || true || ""

このクエリーはすべてのレコードにマッチします。このユーザーはデータベース中のすべてのレコードを取得するでしょう。このユーザーには悪意があったのかもしれません。

ユーザーからの入力では値だけを受け取るようにする方がよいです。これは、ユーザーからの入力には @&& のような演算子を受け付けないようにするということです。もし、演算子も受け付けるようにするなら、ユーザーは悪意のあるクエリーを作ることができます。

ユーザーの入力が値だけなら、入力された値をエスケープすることで悪意のあるクエリーを防ぐことができます。以下はユーザーの入力をどのようにエスケープすればよいかのリストです。

  • 真の値: true に変換してください。

  • 負の値: false に変換してください。

  • 数値: 整数 または 浮動小数点数 に変換してください。例えば、 1.2-10314e-2 といった具合です。

  • 文字列:文字列中の "\" で、 \\\ で置換してください。その後、置換した文字列を " で囲んでください。例えば、 double " quote and back \ slash"double \" quote and back \\ slash" に変換します。

7.12.2.2. サンプルデータ

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

実行例:

table_create Entries TABLE_PAT_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 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},
{"_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._keyEntries.content は両方とも全文検索できます。

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

7.12.2.3. リテラル

7.12.2.3.1. 整数

整数リテラルは 1234567890 のような 0 から 9 の並びです。 +29-29 のように符号として最初に + または - をつけることができます。整数リテラルは10進数です。8進数や16進数などは使えません。

整数リテラルの最大値は 9223372036854775807= 2 ** 63 - 1 )です。最小値は -9223372036854775808= -(2 ** 63) )です。

7.12.2.3.2. 浮動小数点数

浮動小数点数リテラルは 3.14 のように、まず 0 から 9 、次に . 、最後に 0 から 9 という並びです。 +3.14-3.14 のように符号として最初に + または - をつけることができます。 ${基数}e${指数}${基数}E${指数} というフォーマットもサポートしています。例えば、 314e-23.14 と同じです。

7.12.2.3.3. 文字列

文字列リテラルは "..." です。リテラル中の "\" というように \ を前につけてエスケープします。例えば、 "Say \"Hello!\"."Say "Hello!". という文字列のリテラルです。

文字列エンコーディングはデータベースのエンコーディングと合わせなければいけません。デフォルトのエンコーディングはUTF-8です。これは configure の --with-default-encoding オプションや groonga 実行ファイル--encodiong などで変更できます。

7.12.2.3.4. 真偽値

真偽値のリテラルは truefalse です。 true は真という意味で、 false は偽という意味です。

7.12.2.3.5. NULL

NULLのリテラルは null です。GroongaはNULL値をサポートしてませんが、NULLリテラルをサポートしています。

7.12.2.3.6. 時間

注釈

これはgroonga独自の記法です。

時間のリテラルはありません。文字列での時間記法、整数での時間記法または浮動小数点数での時間記法を使ってください。

文字列での時間記法は "YYYY/MM/DD hh:mm:ss.uuuuuu" または "YYYY-MM-DD hh:mm:ss.uuuuuu" です。 YYYY は西暦、 MM は月、 DD は日、 hh は時、 mm は分、 ss は秒、 uuuuuu はマイクロ秒です。ローカル時間です。例えば、 "2012/07/23 02:41:10.436218" はISO 8601形式では 2012-07-23T02:41:10.436218 になります。

整数での時間記法はUTC時間で1970年1月1日0時0分0秒からの経過秒数を使います。この時間はPOSIX時間とも呼ばれています。例えば、 1343011270 はISO 8601形式では 2012-07-23T02:41:10Z になります。

浮動小数点数での時間記法はUTC時間で1970年1月1日0時0分0秒からの経過秒数と経過マイクロ秒数を使います。例えば、 1343011270.436218 はISO 8601形式では 2012-07-23T02:41:10.346218Z になります。

7.12.2.3.7. 座標値

注釈

これはgroonga独自の記法です。

座標値のリテラルはありません。文字列での座標値記法を使ってください。

文字列での座標値記法には以下のパターンがあります。

  • "ミリ秒表記の緯度xミリ秒表記の経度"

  • "ミリ秒表記の緯度,ミリ秒表記の経度"

  • "度数表記の緯度x度数表記の経度"

  • "度数表記の緯度,度数表記の経度"

x, のどちらも区切り文字として使えます。緯度と経度はミリ秒または度数で指定します。

7.12.2.3.8. 配列

配列リテラルは [element1, element2, ...] です。

7.12.2.3.9. オブジェクトリテラル

オブジェクトのリテラルは {name1: value1, name2: value2, ...} です。groongaはまだオブジェクトリテラルをサポートしていません。

7.12.2.4. 制御構文

スクリプト構文は文をサポートしていません。そのため、 if のような制御文を使うことはできません。制御用の構文は A ? B : C 式だけ使うことができます。

A ? B : CA が真なら B を返して、そうでなかったら C を返します。

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

実行例:

select Entries --filter 'n_likes == (_id == 1 ? 5 : 3)'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         3
#       ],
#       [
#         [
#           "_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
#       ]
#     ]
#   ]
# ]

この式は _id カラムの値が 1n_likes カラムの値が 5 または _id カラムの値が 1 ではなく n_likes カラムの値が 3 のレコードにマッチします。

7.12.2.5. グループ化

構文は (...) です。 ... はカンマ区切りの式のリストです。

(...) は1つ以上の式をグループ化します。グループ化された式は1つの式として処理されます。 a && b || cab の両方がマッチするか、 c がマッチすれば式全体がマッチする、という意味になります。 a && (b || c)a がマッチして bc はどちらか一方がマッチすれば式全体がマッチする、という意味になります。

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

実行例:

select Entries --filter 'n_likes < 5 && content @ "senna" || content @ "fast"'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         3
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         4,
#         "Good-bye Senna",
#         "I migrated all Senna system!",
#         3
#       ],
#       [
#         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 --filter 'n_likes < 5 && (content @ "senna" || content @ "fast")'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         4,
#         "Good-bye Senna",
#         "I migrated all Senna system!",
#         3
#       ]
#     ]
#   ]
# ]

最初の式はグループ化していません。この式は n_likes < 5content @ "senna" の両方がマッチするか content @ "fast" がマッチするレコードにマッチします。

2番目の式はグループ化しています。この式は n_likes < 5 にマッチして、 content @ "senna"content @ "fast" は少なくともどちらか一方にマッチするレコードにマッチします。

7.12.2.6. 関数呼び出し

構文は name(arugment1, argument2, ...) です。

name(argument1, argument2, ...)name という関数を引数 argument1, argument2, ... で呼び出します。

利用可能な関数の一覧は 関数 を参照してください。

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

実行例:

select Entries --filter 'edit_distance(_key, "Groonga") <= 1'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は edit_distance を使っています。この式は _key カラムの値が "Groonga" に似ているレコードにマッチします。 "Groonga" との類似度は編集距離で計算します。編集距離が1文字以下なら似ているとします。この場合は "Groonga""Mroonga" が似ている値です。

7.12.2.7. 基本的な演算子

groongaはECMAScriptで定義されている演算子をサポートしています。

7.12.2.7.1. 算術演算子

以下は算術演算子の説明です。

7.12.2.7.1.1. 加算演算子

構文は number1 + number2 です。

この演算子は number1number2 を足した結果を返します。

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

実行例:

select Entries --filter 'n_likes == 10 + 5'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 15 (= 10 + 5) のレコードにマッチします。

7.12.2.7.1.2. 減算演算子

構文は number1 - number2 です。

この演算子は number2 から number1 を引いた結果を返します。

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

実行例:

select Entries --filter 'n_likes == 20 - 5'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 15 (= 20 - 5) のレコードにマッチします。

7.12.2.7.1.3. 乗算演算子

構文は number1 * number2 です。

この演算子は number1number2 を掛けた結果を返します。

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

実行例:

select Entries --filter 'n_likes == 3 * 5'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 15 (= 3 * 5) のレコードにマッチします。

7.12.2.7.1.4. 除算演算子

構文は number1 / number2number1 % number2 です。

この演算子は number2number1 で割ります。 / は商を返します。 % は余りを返します。

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

実行例:

select Entries --filter 'n_likes == 26 / 7'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "_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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 3 (= 26 / 7) のレコードにマッチします。

実行例:

select Entries --filter 'n_likes == 26 % 7'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 (= 26 % 7) の値にマッチします。

7.12.2.7.2. 論理演算子

以下は論理演算子の説明です。

7.12.2.7.2.1. 論理否定演算子

構文は !condition です。

この演算子は condition の真偽値を反転します。

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

実行例:

select Entries --filter '!(n_likes == 5)'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         4
#       ],
#       [
#         [
#           "_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
#       ],
#       [
#         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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 ではない式にマッチします。

7.12.2.7.2.2. 論理積演算子

構文は condition1 && condition2 です。

この演算子は condition1condition2 の両方が真のときに真を返し、そうでなければ偽を返します。

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

実行例:

select Entries --filter 'content @ "fast" && n_likes >= 10'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は content カラムの値が fast を含んでいて、 n_likes カラムの値が 10 以上のレコードにマッチします。

7.12.2.7.2.3. 論理和演算子

構文は condition1 || condition2 です。

この演算子は condition1condition2 のどちらか一方が真のときに真を返し、そうでなければ偽を返します。

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

実行例:

select Entries --filter 'n_likes == 5 || n_likes == 10'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "_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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 または 10 のレコードにマッチします。

7.12.2.7.2.4. 論理差演算子

構文は condition1 &! condition2 です。

この演算子は condition1 が真で condition2 が偽のときに真を返し、そうでなければ偽を返します。差集合を返すということです。

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

実行例:

select Entries --filter 'content @ "fast" &! content @ "mroonga"'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は content カラムの値が fast を含んでいるが mroonga を含んでいないレコードにマッチします。

7.12.2.7.3. ビット演算子

以下はビット演算子の説明です。

7.12.2.7.3.1. ビット否定演算子

構文は ~number です。

この演算子は number の各ビットを反転した結果を返します。

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

実行例:

select Entries --filter '~n_likes == -6'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 のレコードにマッチします。なぜならば、 5 の各ビットを反転すると -6 になるからです。

7.12.2.7.3.2. ビット論理積演算子

構文は number1 & number2 です。

この演算子は number1number2 をビット単位で論理積をした結果を返します。

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

実行例:

select Entries --filter '(n_likes & 1) == 1'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         4
#       ],
#       [
#         [
#           "_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
#       ],
#       [
#         3,
#         "Mroonga",
#         "I also started to use Mroonga. It's also very fast! Really fast!",
#         15
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が偶数のレコードにマッチします。なぜならば、偶数と 1 のビット単位の論理積は 1 になり、奇数と 1 のビット単位の論理積は 0 になるからです。

7.12.2.7.4. ビット論理和演算子

構文は number1 | number2 です。

この演算子は number1number2 をビット単位で論理和した結果を返します。

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

実行例:

select Entries --filter 'n_likes == (1 | 4)'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 (= 1 | 4) のレコードにマッチします。

7.12.2.7.5. ビット排他的論理和演算子

構文は number1 ^ number2 です。

この演算子は number1number2 をビット単位で排他的論理和した結果を返します。

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

実行例:

select Entries --filter 'n_likes == (10 ^ 15)'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 (= 10 ^ 15) の値にマッチします。

7.12.2.7.6. シフト演算子

以下はシフト演算子の説明です。

7.12.2.7.6.1. 左シフト演算子

構文は number1 << number2 です。

この演算子は number1 のビットを左に number2 ビットシフトする。

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

実行例:

select Entries --filter 'n_likes == (5 << 1)'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 10 (= 5 << 1) のレコードにマッチします。

7.12.2.7.6.2. 符号付き右シフト演算子

構文は number1 >> number2 です。

この演算子は number1 のビットを右に number2 ビットシフトします。結果の符号は number1 の符号と同じです。

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

実行例:

select Entries --filter 'n_likes == -(-10 >> 1)'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 (= -(-10 >> 1) = -(-5)) のレコードにマッチします。

7.12.2.7.6.3. 符号なし右シフト演算子

構文は number1 >>> number2 です。

この演算子は number1 のビットを右に number2 ビットシフトします。一番左の number2 ビットには 0 が入ります。

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

実行例:

select Entries --filter 'n_likes == (2147483648 - (-10 >>> 1))'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "content",
#           "Text"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ]
#       ],
#       [
#         1,
#         "The first post!",
#         "Welcome! This is my first post!",
#         5
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 (= 2147483648 - (-10 >>> 1) = 2147483648 - 2147483643) のレコードにマッチします。

7.12.2.7.7. 比較演算子

以下は比較演算子の説明です。

7.12.2.7.7.1. 等価演算子

構文は object1 == object2 です。

この演算子は object1object2 と等しいときは真を返し、そうでなければ偽を返します。

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

実行例:

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

この式は n_likes カラムの値が 5 の値にマッチします。

7.12.2.7.7.2. 不等価演算子

構文は object1 != object2 です。

この演算子は object1object2 と等しくないときに真を返し、そうでなければ偽を返します。

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

実行例:

select Entries --filter 'n_likes != 5'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         4
#       ],
#       [
#         [
#           "_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
#       ],
#       [
#         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
#       ]
#     ]
#   ]
# ]

この式は n_likes カラムの値が 5 ではない式にマッチします。

7.12.2.7.7.3. 小なり演算子

TODO: ...

7.12.2.7.7.4. 以下演算子

TODO: ...

7.12.2.7.7.5. 大なり演算子

TODO: ...

7.12.2.7.7.6. 以上演算子

TODO: ...

7.12.2.8. 代入演算子

7.12.2.8.1. 加算代入演算子

構文は column += value です。

この演算子は column1column2 を加算代入します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score += n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         4
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         4
#       ],
#       [
#         "Groonga",
#         10,
#         11
#       ],
#       [
#         "Mroonga",
#         15,
#         16
#       ],
#       [
#         "The first post!",
#         5,
#         6
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score + n_likes' という加算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 + 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.2. 減算代入演算子

構文は column1 -= column2 です。

この演算子は column1 から column2 を減算代入します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score -= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         -2
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         -2
#       ],
#       [
#         "Groonga",
#         10,
#         -9
#       ],
#       [
#         "Mroonga",
#         15,
#         -14
#       ],
#       [
#         "The first post!",
#         5,
#         -4
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score - n_likes' という減算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 - 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.3. 乗算代入演算子

構文は column1 *= column2 です。

この演算子は column1column2 を乗算演算する。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score *= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         3
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         3
#       ],
#       [
#         "Groonga",
#         10,
#         10
#       ],
#       [
#         "Mroonga",
#         15,
#         15
#       ],
#       [
#         "The first post!",
#         5,
#         5
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score * n_likes' という乗算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 * 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.4. 除算代入演算子

構文は column1 /= column2 です。

この演算子は column1column2 を除算代入します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score /= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         0
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         0
#       ],
#       [
#         "Groonga",
#         10,
#         0
#       ],
#       [
#         "Mroonga",
#         15,
#         0
#       ],
#       [
#         "The first post!",
#         5,
#         0
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score / n_likes' という除算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 / 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.5. 剰余代入演算子

構文は column1 %= column2 です。

この演算子は column1column2 を剰余代入します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score %= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         1
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         1
#       ],
#       [
#         "Groonga",
#         10,
#         1
#       ],
#       [
#         "Mroonga",
#         15,
#         1
#       ],
#       [
#         "The first post!",
#         5,
#         1
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score % n_likes' という除算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 % 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.6. 左シフト代入演算子

構文は column1 << column2 です。

この演算子は column1 のビットを左に column2 左ビットシフト代入演算します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score <<= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         8
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         8
#       ],
#       [
#         "Groonga",
#         10,
#         1024
#       ],
#       [
#         "Mroonga",
#         15,
#         32768
#       ],
#       [
#         "The first post!",
#         5,
#         32
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score << n_likes' という左ビットシフト代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 << 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.7. 符号あり右シフト代入演算子

構文は column1 >>= column2 です。

この演算子は column1 のビットを column2 右ビットシフト代入演算します。

7.12.2.8.8. 符号なし右シフト代入演算子

構文は column1 >>>= column2 です。

この演算子は column1 のビットを column2 符号なし右ビットシフト代入演算します。

7.12.2.8.9. ビット論理積代入演算子

構文は column1 &= column2 です。

この演算子は column1column2 をビット論理積代入演算します。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score &= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         1
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         1
#       ],
#       [
#         "Groonga",
#         10,
#         0
#       ],
#       [
#         "Mroonga",
#         15,
#         1
#       ],
#       [
#         "The first post!",
#         5,
#         1
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score & n_likes' というビット論理積代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Groonga"を格納しているレコードの値は10です。

そのため、 1 & 10 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.10. ビット論理和代入演算子

構文は column1 |= column2 です。

この演算子は column1column2 をビット論理和代入演算する。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score |= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         3
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         3
#       ],
#       [
#         "Groonga",
#         10,
#         11
#       ],
#       [
#         "Mroonga",
#         15,
#         15
#       ],
#       [
#         "The first post!",
#         5,
#         5
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score | n_likes' というビット論理和代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Groonga"を格納しているレコードの値は10です。

そのため、 1 | 10 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.8.11. ビット排他的論理和代入演算子

構文は column1 ^= column2 です。

この演算子は column1column2 をビット論理和代入演算する。

実行例:

select Entries --output_columns _key,n_likes,_score --filter true --scorer '_score ^= n_likes'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         5
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ],
#         [
#           "n_likes",
#           "UInt32"
#         ],
#         [
#           "_score",
#           "Int32"
#         ]
#       ],
#       [
#         "Good-bye Senna",
#         3,
#         2
#       ],
#       [
#         "Good-bye Tritonn",
#         3,
#         2
#       ],
#       [
#         "Groonga",
#         10,
#         11
#       ],
#       [
#         "Mroonga",
#         15,
#         14
#       ],
#       [
#         "The first post!",
#         5,
#         4
#       ]
#     ]
#   ]
# ]

--filter による _score の値はこの場合は常に1です。その後、'_score = _score ^ n_likes' という減算代入演算をそれぞれのレコードへ適用します。

例えば、 _key として"Good-bye Senna"を格納しているレコードの _score の値は3です。

そのため、 1 ^ 3 という式が評価されてから _score カラムへと演算結果が保存されます。

7.12.2.9. 独自の演算子

スクリプト構文はECMAScriptの構文に独自の二項演算子を追加しています。これらは検索に特化した操作をします。演算子の最初の文字は @ または * です。

7.12.2.9.1. マッチ演算子

構文は column @ value です。

この演算子は column の転置インデックスを使って value を検索します。普通は全文検索をしますが、タグ検索もできます。これは、タグ検索も転置インデックスを使って実現しているからです。

クエリー構文 はデフォルトでこの演算子を使っています。

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

実行例:

select Entries --filter 'content @ "fast"' --output_columns content
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "content",
#           "Text"
#         ]
#       ],
#       [
#         "I started to use Groonga. It's very fast!"
#       ],
#       [
#         "I also started to use Mroonga. It's also very fast! Really fast!"
#       ]
#     ]
#   ]
# ]

この式は content カラムの値に fast という単語を含んでいるレコードにマッチします。

7.12.2.9.2. 前方一致検索演算子

構文は column @^ value です。

この条件式は value で前方一致検索します。前方一致検索は value で始まる単語を含むレコードを検索します。

カラムの値を高速に前方一致検索できます。ただし、そのカラムにはインデックスを作成し、そのインデックス用のテーブルをパトリシアトライ( TABLE_PAT_KEY )またはダブル配列トライ( TABLE_DAT_KEY )にしなければいけません。あるいは、パトリシアトライテーブルまたはダブル配列テーブルの _key も高速に前方一致検索できます。 _key にインデックスを作成する必要はありません。

他の種類のテーブルでも前方一致検索を使えますがレコード全件を処理します。レコード数が少ない場合には問題ありませんが、レコード数が多いと時間がかかります。

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

実行例:

select Entries --filter '_key @^ "Goo"' --output_columns _key
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ]
#       ],
#       [
#         "Good-bye Tritonn"
#       ],
#       [
#         "Good-bye Senna"
#       ]
#     ]
#   ]
# ]

この式は _key カラムの値が Goo で始まる単語を含むレコードにマッチします。この式には Good-bye SennaGood-bye Tritonn がマッチします。

7.12.2.9.3. 後方一致検索演算子

構文は column @$ value です。

この演算子は value で後方一致検索します。後方一致検索は value で終わる単語を含むレコードを検索します。

カラムの値を高速に後方一致検索できます。ただし、そのカラムにはインデックスを作成し、そのインデックス用のテーブルを KEY_WITH_SIS フラグ付きのパトリシアトライテーブル( TABLE_PAT_KEY )にしなければいけません。 KEY_WITH_SIS フラグ付きのパトリシアトライテーブル( TABLE_PAT_KEY )の _key 擬似カラムの値も高速に後方一致検索できます。 _key にはインデックスを作成する必要はありません。 _key ベースの高速な後方一致検索よりもカラムベースの高速な後方一致検索を使うことをおすすめします。 _key ベースの高速な後方一致検索は自動的に登録された部分文字列も返ってきます。(TODO: 後方一致検索に関するドキュメントを書いてここからリンクを張る。)

注釈

高速な後方一致検索は日本語のひらがななど非ASCII文字にしか使えません。ASCII文字には高速な後方一致検索を使えません。

後方一致検索は他の種類のテーブルもしくはパトリシアトライを KEY_WITH_SIS フラグなしで使用しているテーブルに対しても使えますが、レコード全件を処理します。レコード数が少ない場合には問題ありませんが、レコード数が多いと時間がかかります。

簡単な例です。ASCII文字ではない文字である日本語のひらがなに対して高速な後方一致検索をしています。

実行例:

table_create Titles TABLE_NO_KEY
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create Titles content COLUMN_SCALAR ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
table_create SuffixSearchTerms TABLE_PAT_KEY|KEY_WITH_SIS ShortText
# [[0, 1337566253.89858, 0.000355720520019531], true]
column_create SuffixSearchTerms index COLUMN_INDEX Titles content
# [[0, 1337566253.89858, 0.000355720520019531], true]
load --table Titles
[
{"content": "ぐるんが"},
{"content": "むるんが"},
{"content": "せな"},
{"content": "とりとん"}
]
# [[0, 1337566253.89858, 0.000355720520019531], 4]
select Titles --query 'content:$んが'
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "_id",
#           "UInt32"
#         ],
#         [
#           "content",
#           "ShortText"
#         ]
#       ],
#       [
#         2,
#         "むるんが"
#       ],
#       [
#         1,
#         "ぐるんが"
#       ]
#     ]
#   ]
# ]

この式は content カラムの値が んが で終わるレコードにマッチします。この場合は ぐるんがむるんが にマッチします。

7.12.2.9.4. 近傍検索演算子

構文は以下のどれかです。:

column *N "word1 word2 ..."
column *N${MAX_INTERVAL} "word1 word2 ..."

2つめの形式の例は次の通りです。

column *N29 "word1 word2 ..."
column *N-1 "word1 word2 ..."

最初の例は近いと判断する最大距離として 29 を使うという意味です。

2つめの例は近いと判断する最大距離として -1 を使うという意味です。 -1 はどれだけ離れていてもよいという意味です。

この演算子は word1 word2 ... という単語で近傍検索します。近傍検索はすべての単語が含まれていてかつそれぞれが指定した順番で出現していてかつそれぞれの単語が指定した距離以内にあるレコードを検索します。

近いと判断する最大距離のでファオルトは 10 です。距離の単位はN-gram系のトークナイザーでは文字数で、形態素解析系のトークナイザーでは単語数です。

(TODO: TokenBigram はASCIIだけの単語はトークンに分割しないという説明を追加すること。このため、 TokenBigram はN-gram系のトークナイザーだけどASCIIだけの単語を扱う時の単位は単語数になる。)

column 用の全文検索用インデックスカラムを定義しておく必要があることに注意してください。

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

実行例:

select Entries --filter 'content *N "I fast"'      --output_columns content
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "content",
#           "Text"
#         ]
#       ],
#       [
#         "I started to use Groonga. It's very fast!"
#       ]
#     ]
#   ]
# ]
select Entries --filter 'content *N "I Really"'    --output_columns content
# [[0, 1337566253.89858, 0.000355720520019531], [[[0], [["content", "Text"]]]]]
select Entries --filter 'content *N "also Really"' --output_columns content
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         1
#       ],
#       [
#         [
#           "content",
#           "Text"
#         ]
#       ],
#       [
#         "I also started to use Mroonga. It's also very fast! Really fast!"
#       ]
#     ]
#   ]
# ]

最初の式は Ifast が含まれていて、かつ、これらの単語が10単語以内近くにあるレコードにマッチします。そのため I also started to use mroonga. It's also very fast! ... にマッチします。 Ifast の間の単語数はちょうど10です。

二番目の式は IReally が含まれていて、かつ、これらの単語が10単語以内近くにあるレコードにマッチします。そのため、 I also st arted to use mroonga. It's also very fast! Really fast! はマッチしません。 IReally の間の単語数は11です。

三番目の式は alsoReally が含まれていて、かつ、これらの単語が10単語以内近くにあるレコードにマッチします。そのため、 I also started to use mroonga. It's also very fast! Really fast! にマッチします。 alsoReally の間の単語数は10です。

7.12.2.9.6. 単語抽出演算子

構文は _key *T "document" です。

この演算子は document から単語を抽出します。単語は _key のテーブルのキーとして登録されていなければいけません。

テーブルはパトリシアトライ( TABLE_PAT_KEY )またはダブル配列トライ( TABLE_DAT_KEY )でなければいけません。ハッシュテーブル( TABLE_HASH_KEY )や配列( TABLE_NO_KEY )は最長共通接頭辞検索(Longest Common Prefix Search)できないため使えません。この演算子は最長共通接頭辞検索を使っています。

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

実行例:

table_create Words TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
# [[0, 1337566253.89858, 0.000355720520019531], true]
load --table Words
[
{"_key": "groonga"},
{"_key": "mroonga"},
{"_key": "Senna"},
{"_key": "Tritonn"}
]
# [[0, 1337566253.89858, 0.000355720520019531], 4]
select Words --filter '_key *T "Groonga is the successor project to Senna."' --output_columns _key
# [
#   [
#     0,
#     1337566253.89858,
#     0.000355720520019531
#   ],
#   [
#     [
#       [
#         2
#       ],
#       [
#         [
#           "_key",
#           "ShortText"
#         ]
#       ],
#       [
#         "groonga"
#       ],
#       [
#         "senna"
#       ]
#     ]
#   ]
# ]

この式は文書 Groonga is the successor project to Senna. に含まれている単語を抽出します。今回は WordsNormalizerAuto ノーマライザーが指定されています。そのため、 Words には groonga とロードしていますが Groonga も抽出できています。また、すべてての抽出された単語も正規化されています。

7.12.2.9.7. 正規表現演算子

バージョン 5.0.1 で追加.

構文は column @~ "pattern" です。

この演算子は正規表現 pattern でレコードを検索します。もし、レコードの column の値が pattern にマッチしたら、そのレコードはマッチしたということです。

pattern は正規表現の構文になっていなければいけません。正規表現の構文の詳細は 正規表現 を参照してください。

以下の例はパターンとして .roonga を使っています。このパターンは GroongaMroonga といった文字列にマッチします。

実行例:

select Entries --filter 'content @~ ".roonga"'
# [
#   [
#     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
#       ]
#     ]
#   ]
# ]

多くの場合、各レコードに対して順に正規表現を評価します。そのため、多くのレコードがある場合は遅くなるかもしれません。

いくつかのケースでは、Groongaはインデックスを使って正規表現を評価します。これはとても高速です。詳細は 正規表現 を参照してください。