Groonga 13.0.8リリース
Groonga 13.0.8をリリースしました!
それぞれの環境毎のインストール方法: インストール
変更内容
主な変更点は以下の通りです。
改良
-
[column_create]
column_create
に新しいフラグCOLUMN_FILTER_SHUFFLE
,COLUMN_FILTER_BYTE_DELTA
,COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
,COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES
を追加しました。これらのフラグは、圧縮前にデータをフィルタリングすることによって
COMPRESS_ZLIB
,COMPRESS_LZ4
,COMPRESS_ZSTD
の圧縮率を高めるためのフラグです。 データによっては、これらのフラグを使っても圧縮率が上がらないこともあります。また、これらのフラグを使うと、カラムの保存や参照に追加の処理が加わるので、これらのフラグを使うと、カラムの保存や参照は確実に遅くなります。効果のあるフラグのみを使う事が重要です。
COMPRESS_ZLIB
,COMPRESS_LZ4
,COMPRESS_ZSTD
を指定してない場合でも、これらのフラグは、圧縮アルゴリズムとして BloscLZ を使うので、これらのフラグを使うことで、ほとんどの場合で非圧縮のカラムよりもカラムサイズを小さくできます。 ただ、データによっては、COMPRESS_ZLIB
,COMPRESS_LZ4
,COMPRESS_ZSTD
を使うだけで十分な場合もあります。 そのため、データによって適切なフラグを設定することをおすすめします。これらのフラグは、
COLUMN_VECTOR
でのみ使用できます。COLUMN_SCALAR
の場合は、これらのフラグは無視されます。では、各フラグにとってどのようなデータが適切かを記載します。
-
COLUMN_FILTER_SHUFFLE
このフラグはNバイト目の要素に着目してデータを並び替えます。
このフラグは、まずベクターカラム内の各要素の0バイト目だけのデータを集めて連続で配置します。 その後、同様に1バイト目のデータだけを集めて連続で配置するということをすべてのバイトに対して繰り返します。
COMPRESS_ZLIB
やCOMPRESS_LZ4
やCOMPRESS_ZSTD
といった圧縮アルゴリズムは同じ値が連続しているデータだと圧縮率が高くなる傾向があります。 このフラグのポイントは、Nバイトごとにデータを並び替えることで同じ値が連続しているデータを作り出すことです。では、具体的にどのような操作をするのかを記載します。
例えば、
UInt32
のベクターカラム[1, 1051, 515]
があるとします。 これをリトルエンディアンのバイト列で表現すると以下のようになります。| Byte 0 | Byte 1 | | Byte 0 | Byte 1 | | Byte 0 | Byte 1 | |--------|--------| |--------|--------| |--------|--------| | 0x00 | 0x01 |, | 0x04 | 0x1b |, | 0x02 | 0x03 |
このフラグは、上記の
Byte 0
の値をまとめて、その後Byte 1
のデータをまとめ以下のようなデータを作るフラグです。 この、Nバイト毎にまとめる操作を以後、シャッフルと呼びます。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x04 | 0x02 |, | 0x01 | 0x1b | 0x03 |
ポイントは「同じ値が連続する箇所があるかどうか?」です。 上記の例を見てみると、シャッフル後のデータは同じ値が連続している箇所がありません。 このようなデータでは、シャッフルしても圧縮率の向上に寄与しないため、このフラグを適用するには不向きなデータです。
一方で、
UInt32
のベクターカラム[1,2,3]というデータでは、シャッフルすると以下のようになります。まず、説明のため
UInt32
:[1,2,3]を以下のようなバイト列表現にします。| Byte 0 | Byte 1 | | Byte 0 | Byte 1 | | Byte 0 | Byte 1 | |--------|--------| |--------|--------| |--------|--------| | 0x00 | 0x01 |, | 0x00 | 0x02 |, | 0x00 | 0x03 |
そして、
UInt32
:[1,2,3]をシャッフルすると以下のようなデータになります。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x00 | 0x00 |, | 0x01 | 0x02 | 0x03 |
UInt32
:[1,2,3]というデータだと、シャッフル後にByte 0
のデータがすべて0になり、同じ値が連続することになります。 したがって、このようなデータは圧縮率の向上に寄与するので、このフラグを適用するのに向いているデータです。 浮動小数点数であれば、符号と指数部が同じデータが該当します。 IEEE 754 形式の単精度浮動小数点数の場合、符号は31ビット目に配置され、指数部は30ビット目から23ビット目に配置されます。 符号ビットと指数部の上位7ビットで最上位のバイトが構成されるので符号ビットと指数部の上位7ビットが同じになれば、シャッフル後は同じ値が連続することになるからです。例えば、
Float32
:[0.5, 0.6]というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように符号ビットと指数部が同一です。| 符号(1bit) | 指数部(8bit) | 仮数部(23bit) | |------------|-------------|------------------------------| | 0 | 0111 1110 | 000 0000 0000 0000 0000 0000 | | 0 | 0111 1110 | 001 1001 1001 1001 1001 1010 |
これを、シャッフルすると以下のようになり、
Byte 3
に同じ値が連続することになります。| Byte 0 | Byte 0 | | Byte 1 | Byte 1 | | Byte 2 | Byte 2 | | Byte 3 | Byte 3 | |--------|--------| |--------|--------| |--------|--------| |--------|--------| | 0x00 | 0x9a |, | 0x00 | 0x99 |, | 0x00 | 0x19 |, | 0x3f | 0x3f |
-
COLUMN_FILTER_BYTE_DELTA
このフラグは、圧縮対象の値のバイト間の差分を計算するフラグです。 このフラグは、隣り合うバイトの差分を計算します。例えば
UInt8
のベクターカラム[1,2,3,4,5]というデータの場合、このフラグを適用すると[1,(2-1),(3-2),(4-3),(5-4)]=[1,1,1,1,1]というデータになります。上記のように差分データを計算することで、同じ値が連続するデータを作り圧縮率を向上させることを狙っています。 ポイントは、各要素間の差分を計算することで、同じ値が連続するデータを作り出すことにあります。
したがって、差分を計算しても同じ値が連続するデータを作り出すことができないデータは、このフラグを適用するには不向きなデータです。 どのようなデータであれば、差分を計算して同じ値が連続するようになるのかを以下に記載します。
まずは、前述の例でもあげた、
UInt8
:[1,2,3,4,5]というような一定のペースで値が増加していくデータです。 一定のペースなので、UInt8
:[1,11,21,31,41]のように10ずつ値が増加するようなデータでも良いです。次に、
UInt8
:[5,5,5,5,5]のように同じ値が連続するデータです。 このデータは差分を計算すると[5,0,0,0,0]となり、0が連続するようになります。逆に、
UInt8
:[1, 255, 2, 200, 1]のように差分を計算しても同じ値が連続しないデータは、このフラグには不向きなデータです。 -
COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
このフラグは、
Float
/Float32
のデータでのみ有効です。COLUMN_FILTER_SHUFFLE
と組み合わせて使うことを想定しています。Float
/Float32
ベクターカラムの各要素の精度を1バイト落とします。精度を落とすとは、浮動小数点数の最下位バイトをすべて0にすることです。例えば、
Float32
:[1.25, 3.67, 4.55]というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように表現できます。| 符号(1bit) | 指数部(8bit) | 仮数部(23bit) | |------------|-------------|------------------------------| | 0 | 0111 1111 | 010 0000 0000 0000 0000 0000 | | 0 | 1000 0000 | 110 1010 1110 0001 0100 1000 | | 0 | 1000 0001 | 001 0001 1001 1001 1001 1010 |
このフラグを適用すると、最下位バイトをすべて0にするので以下のようなデータになります。 仮数部の最下位バイトが0になっていることに注目してください。
| 符号(1bit) | 指数部(8bit) | 仮数部(23bit) | |------------|-------------|------------------------------| | 0 | 0111 1111 | 010 0000 0000 0000 0000 0000 | | 0 | 1000 0000 | 110 1010 1110 0001 0000 0000 | | 0 | 1000 0001 | 001 0001 1001 1001 0000 0000 |
ここまでが、このフラグの効果です。 前述の通り、このフラグは、
COLUMN_FILTER_SHUFFLE
と組み合わせて使うことを想定しています。 そのため、ここから更にデータをシャッフルすることで、圧縮率の向上を期待しています。COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
を適用したデータをシャッフルすると以下のようなデータになります。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | | Byte 2 | Byte 2 | Byte 2 | | Byte 3 | Byte 3 | Byte 3 | |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x00 | 0x00 |, | 0x00 | 0xe1 | 0x99 |, | 0xa0 | 0x6a | 0x91 |, | 0x3f | 0x40 | 0x40 |
Byte 0
に注目してください。Byte 0
に0が連続するデータになります。COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
を適用せずにシャッフルすると以下のようなデータになり、どのバイトも同じ値が連続しなくなります。このように単純にシャッフルしただけでは、圧縮率の向上が見込めないデータでもCOMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
を適用することで、圧縮率の向上が見込める場合があります。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | | Byte 2 | Byte 2 | Byte 2 | | Byte 3 | Byte 3 | Byte 3 | |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x48 | 0x9a |, | 0x00 | 0xe1 | 0x99 |, | 0xa0 | 0x6a | 0x91 |, | 0x3f | 0x40 | 0x40 |
ただし、圧縮対象の浮動小数点数の精度が1バイト分落ちるので、その分不正確なデータになることに注意してください。
-
COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES
このフラグは、
Float
/Float32
のデータでのみ有効です。COLUMN_FILTER_SHUFFLE
と組み合わせて使うことを想定しています。Float
/Float32
ベクターカラムの各要素の精度を2バイト落とします。精度を落とすとは、浮動小数点数の下位2バイトをすべて0にすることです。例えば、
Float32
:[1.25, 3.67, 4.55]というデータは、IEEE 754 形式の単精度浮動小数点数で表現すると以下のように表現できます。| 符号(1bit) | 指数部(8bit) | 仮数部(23bit) | |------------|-------------|------------------------------| | 0 | 0111 1111 | 010 0000 0000 0000 0000 0000 | | 0 | 1000 0000 | 110 1010 1110 0001 0100 1000 | | 0 | 1000 0001 | 001 0001 1001 1001 1001 1010 |
このフラグを適用すると、下位2バイトをすべて0にするので以下のようなデータになります。 仮数部の下位2バイトが0になっていることに注目してください。
| 符号(1bit) | 指数部(8bit) | 仮数部(23bit) | |------------|-------------|------------------------------| | 0 | 0111 1111 | 010 0000 0000 0000 0000 0000 | | 0 | 1000 0000 | 110 1010 0000 0000 0000 0000 | | 0 | 1000 0001 | 001 0001 0000 0000 0000 0000 |
ここまでが、このフラグの効果です。
前述の通り、このフラグは、
COLUMN_FILTER_SHUFFLE
と組み合わせて使うことを想定しています。 そのため、ここから更にデータをシャッフルすることで、圧縮率の向上を期待しています。COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE
を適用したデータをシャッフルすると以下のようなデータになります。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | | Byte 2 | Byte 2 | Byte 2 | | Byte 3 | Byte 3 | Byte 3 | |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x00 | 0x00 |, | 0x00 | 0x00 | 0x00 |, | 0xa0 | 0x6a | 0x91 |, | 0x3f | 0x40 | 0x40 |
Byte 0
とByte 1
に注目してください。Byte 0
とByte 1
に0が連続するデータになります。COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE
を適用せずにシャッフルすると以下のようなデータになり、どのバイトも同じ値が連続しなくなります。このように単純にシャッフルしただけでは、圧縮率の向上が見込めないデータでもCOMPRESS_FILTER_TRUNCATE_PRECISION_2BYTE
を適用することで、圧縮率の向上が見込める場合があります。| Byte 0 | Byte 0 | Byte 0 | | Byte 1 | Byte 1 | Byte 1 | | Byte 2 | Byte 2 | Byte 2 | | Byte 3 | Byte 3 | Byte 3 | |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| |--------|--------|--------| | 0x00 | 0x48 | 0x9a |, | 0x00 | 0xe1 | 0x99 |, | 0xa0 | 0x6a | 0x91 |, | 0x3f | 0x40 | 0x40 |
ただし、圧縮対象の浮動小数点数の精度が2バイト分落ちるので、その分不正確なデータになることに注意してください。
-
-
新しくBloscライブラリーをバンドルしました。
COLUMN_FILTER_SHUFFLE
,COLUMN_FILTER_BYTE_DELTA
,COMPRESS_FILTER_TRUNCATE_PRECISION_1BYTE
,COMPRESS_FILTER_TRUNCATE_PRECISION_2BYTES
フラグがBloscを要求するためです。 -
[status] 新しく
status
の出力に"blosc"
を追加しました。 -
[groonga] 新しく
groonga --version
の出力にblosc
を追加しました。 -
[select] 新しく
select
の引数に--fuzzy_max_distance
を追加しました。(実験的)この引数は、誤字を許容する検索を実行する時に有用です。ユーザーの誤字を自動で補正することができます。
この引数が指定された場合、以下のようにマッチしないクエリーが与えられた時、Groongaは語彙表から
--fuzzy_max_distance
以下の編集距離の語を探して、再度検索します。table_create Memos TABLE_NO_KEY column_create Memos content COLUMN_SCALAR ShortText table_create Lexicon TABLE_PAT_KEY ShortText --default_tokenizer TokenNgram --normalizer NormalizerNFKC150 column_create Lexicon memos_content COLUMN_INDEX|WITH_POSITION Memos content load --table Memos [ {"content": "This is a pen"}, {"content": "That is a pen"} ] select Memos --match_columns content --query "Thjs" --fuzzy_max_distance 1 --output_columns *,_score [ [ 0, 0.0, 0.0 ], [ [ [ 1 ], [ [ "content", "ShortText" ], [ "_score", "Int32" ] ], [ "This is a pen", 1 ] ] ] ]
-
[select] 新しく
select
の引数に--fuzzy_max_expansions
を追加しました。(実験的)--fuzzy_max_distance
を使うと、与えられたクエリーがマッチしない時、語彙表の中から--fuzzy_max_distance
以下の編集距離の語を使って再度検索します。例えば、語彙表に
This
とThat
が存在しているとします。--fuzzy_max_distance 10
でThjs
というクエリーが与えられた時に、Thjs
でマッチしない場合は、語彙表にあるThis
とThat
で検索します。上記の例では、語彙表に
--fuzzy_max_distance
が10以下の語が2つしかありませんが、もし、編集距離が10以下の語が大量に語彙表に存在した場合、それらの語すべてを使って検索するため、パフォーマンスが落ちます。--fuzzy_max_expansions
を使うことで検索に使う編集距離の近い語の数を制限できます。 この引数を使って、ヒット数と検索パフォーマンスのバランスを取ることができます。--fuzzy_max_expansions
のデフォルト値は0で、0の場合は語彙表にある編集距離が--fuzzy_max_distance
以下の語すべてを使って検索をします。 -
[select] 新しく
select
の引数に--fuzzy_max_distance_ratio
を追加しました。(実験的)--fuzzy_max_distance
はすべてのクエリーに対して同じ値が設定されます。したがって、例えば "abc OR defghijklmn" というクエリーが与えられたときは "abc" と "defghijklmn" の両方に--fuzzy_max_distance
の値が設定されます。しかし、検索するキーワードによって、誤字をどのくらい許容するかは異なっていることが多いです。 例えば、"abc"は文字数が少ないので、誤字は1文字だけ許容する一方、"defghijklmn"は文字数が多いので、誤字は3文字許容するというようなことが発生します。
--fuzzy_max_distance_ratio
は文字数によって、編集距離を自動で変更するためのものです。 この引数によって、キーワード毎に異なる編集距離を設定できます。--fuzzy_max_distance_ratio FUZZY_MAX_DISTANCE
とすると、編集距離は"文字数 * FUZZY_MAX_DISTANCE"(小数点以下は切り捨てされます)と計算されます。 "FUZZY_MAX_DISTANCE" は 0.34 を推奨しています。 これは、0.34にするとElasticsearchのfuzziness=AUTO
とほぼ同じ値になるためです。 -
[select] 新しく
select
の引数に--fuzzy_prefix_length
を追加しました。(実験的)--fuzzy_max_distance
を使う検索を高速化するための引数です。検索キーワードの先頭から
--fuzzy_prefix_length
に設定した文字数分が共通のデータのみヒットするようになります。--fuzzy_max_distance
が大きくなると、処理対象が増加し遅くなるため、最初に先頭N文字が共通な文字列にのみ処理対象を絞ることで高速に処理できることが多いです。 -
[cast] 以下のように、
"[0.0, 1.0, 1.1, ...]"
をFloat
/Float32
のベクターカラムへのキャストできるようにしました。plugin_register functions/vector table_create Data TABLE_NO_KEY column_create Data numbers COLUMN_VECTOR Float32 table_create Numbers TABLE_PAT_KEY Float32 column_create Numbers data_numbers COLUMN_INDEX Data numbers load --table Data [ {"numbers": "[0.1, 0.0, -0.2]"}, {"numbers": "[-3, 2, -4294967296, 4294967296]"} ] dump --dump_plugins no --dump_schema no load --table Data [ ["_id","numbers"], [1,[0.1,0.0,-0.2]], [2,[-3.0,2.0,-4.294967e+09,4.294967e+09]] ] column_create Numbers data_numbers COLUMN_INDEX Data numbers select Data --filter 'vector_size(numbers) == 3' [ [ 0, 0.0, 0.0 ], [ [ [ 1 ], [ [ "_id", "UInt32" ], [ "numbers", "Float32" ] ], [ 1, [ 0.1, 0.0, -0.2 ] ] ] ] ]
-
[fuzzy_search]
max_expansion
オプションの名前をmax_expansions
に変更しました。max_expansion
オプションは非推奨になりますが、後方互換性を維持するため引き続き使えます。 -
masterブランチの名前をmainに変更しました。
-
[RPM] CMakeを使ってビルドするようにしました。
-
[Debian] Debian trixie をサポートしました。
修正
-
[fuzzy_search] ヒットするはずのレコードがヒットしない問題を修正しました。
-
[near-phrase-search] 以下のように最初のフレーズグループに何もヒットしない時にGroongaがクラッシュする問題を修正しました。
table_create Entries TABLE_NO_KEY column_create Entries content COLUMN_SCALAR Text table_create Terms TABLE_PAT_KEY ShortText \ --default_tokenizer TokenNgram \ --normalizer NormalizerNFKC121 column_create Terms entries_content COLUMN_INDEX|WITH_POSITION \ Entries content load --table Entries [ {"content": "x y z"} ] select Entries \ --match_columns Terms.entries_content.content \ --query '*NPP1"(NONEXISTENT) (z)"' \ --output_columns '_score, content'