お知らせ - 10系#
10.1.1リリース - 2021-01-25#
改良#
[select] Apache Arrow形式でUInt64の値の出力をサポートしました。
[select] Apache Arrow形式で以下のようにヒット数の出力をサポートしました。
-- metadata -- GROONGA:n-hits: 10
[query] "order by estimated size" の最適化をサポートしました。
通常、ヒット数の少ない条件から最初に実行すると、高速に検索できます。
"A (ヒット数が多い) && B (ヒット数が少ない)" より "B (ヒット数が少ない) && A (ヒット数が多い)" 方が高速です。
これは、よく知られた最適化ですが、自分で条件を並び替える必要があります。
Groongaは、 "order by estimated size" の最適化を使うことで、自動的にこの並び替えを実行します。
この最適化は、
GRN_ORDER_BY_ESTIMATED_SIZE_ENABLE=yes
で有効になります。
[between] 以下の改良で、パフォーマンスを改善しました。
between()
でシーケンシャルサーチを使うかどうかの判断の精度を改善しました。between()
の結果を結果セットに一度にセットするよう改善しました。
[select] 前方一致検索のパフォーマンスを改善しました。
例えば、以下のような "*" を使った前方一致検索のパフォーマンスが向上します。
table_create Memos TABLE_PAT_KEY ShortText table_create Contents TABLE_PAT_KEY ShortText --normalizer NormalizerAuto column_create Contents entries_key_index COLUMN_INDEX Memos _key load --table Memos [ {"_key": "(groonga) Start to try!"}, {"_key": "(mroonga) Installed"}, {"_key": "(groonga) Upgraded!"} ] select \ --table Memos \ --match_columns _key \ --query '\\(groonga\\)*'
[トークナイザー][TokenMecab] トークンカラムを並列で構築する際のパフォーマンスを改善しました。 [GitHub#1158][naoaさんがパッチ提供]
修正#
[sub_filter]
slices[].filter
内でsub_filter
が動作しない問題を修正しました。例えば、以下のクエリーでは、この問題によって、
sub_filter
の結果は0件になります。table_create Users TABLE_HASH_KEY ShortText column_create Users age COLUMN_SCALAR UInt8 table_create Memos TABLE_NO_KEY column_create Memos user COLUMN_SCALAR Users column_create Memos content COLUMN_SCALAR Text load --table Users [ {"_key": "alice", "age": 9}, {"_key": "bob", "age": 29} ] load --table Memos [ {"user": "alice", "content": "hello"}, {"user": "bob", "content": "world"}, {"user": "alice", "content": "bye"}, {"user": "bob", "content": "yay"} ] select \ --table Memos \ --slices[adult].filter '_id > 1 && sub_filter(user, "age >= 18")'
ハッシュテーブルに対して、繰り返し大量のデータを追加、削除すると、Groongaがクラッシュしたり、データの追加ができなくなる可能性がある問題を修正しました。
感謝#
naoaさん
10.1.0リリース - 2020-12-29#
改良#
[highlight_html] 全角スペースをハイライト対処から除外しました。[PGroonga#GitHub#155][Hung Nguyen Vさんが報告]
今までは、以下のように先頭の全角スペースも含めてハイライト対象としていました。
table_create Entries TABLE_NO_KEY column_create Entries body COLUMN_SCALAR ShortText table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto column_create Terms document_index COLUMN_INDEX|WITH_POSITION Entries body load --table Entries [ {"body": "Groonga 高速!"} ] select Entries --output_columns \ --match_columns body --query '高速' \ --output_columns 'highlight_html(body)' [ [ 0, 0.0, 0.0 ], [ [ [ 1 ], [ [ "highlight_html", null ] ], [ "Groonga<span class=\"keyword\"> 高速</span>!" ] ] ] ]
しかし、この全角スペースはハイライト対象としては不要です。そのため、このリリースから
highlight_html()
は先頭の全角スペースを削除します。
[status] 新しい項目
features
を追加しました。以下のように、Groongaのどの機能が有効なのかを表示できます。
status --output_pretty yes [ [ 0, 0.0, 0.0 ], { "alloc_count": 361, "starttime": 1608087311, "start_time": 1608087311, "uptime": 35, "version": "10.1.0", "n_queries": 0, "cache_hit_rate": 0.0, "command_version": 1, "default_command_version": 1, "max_command_version": 3, "n_jobs": 0, "features": { "nfkc": true, "mecab": true, "message_pack": true, "mruby": true, "onigmo": true, "zlib": true, "lz4": false, "zstandard": false, "kqueue": false, "epoll": true, "poll": false, "rapidjson": false, "apache_arrow": false, "xxhash": false } } ]
[status] 新しい項目
apache_arrow
を追加しました。以下のようにGroongaが使うApache Arrowのバージョンを表示できます。
[ [ 0, 1608088628.440753, 0.0006628036499023438 ], { "alloc_count": 360, "starttime": 1608088617, "start_time": 1608088617, "uptime": 11, "version": "10.0.9-39-g5a4c6f3", "n_queries": 0, "cache_hit_rate": 0.0, "command_version": 1, "default_command_version": 1, "max_command_version": 3, "n_jobs": 0, "features": { "nfkc": true, "mecab": true, "message_pack": true, "mruby": true, "onigmo": true, "zlib": true, "lz4": true, "zstandard": false, "kqueue": false, "epoll": true, "poll": false, "rapidjson": false, "apache_arrow": true, "xxhash": false }, "apache_arrow": { "version_major": 2, "version_minor": 0, "version_patch": 0, "version": "2.0.0" } } ]
この項目は、Apache Arrowが有効な場合にのみ表示されます。
[ウィンドウ関数] 対象のテーブルがシャードをまたいでいる場合でも、全てのテーブルを一度に処理するようにしました。(実験的)
今まで、対象のテーブルがシャードをまたいでいた場合、ウインドウ関数はシャード毎に処理をしていました。
そのため、複数のグループキーを使う場合、2番目以降のグループキーの値は1種類でなければなりませんでした。
この改良によって、以下のように複数の種類の値を2番目以降のグループキーで使用できるようになります。
plugin_register sharding plugin_register functions/time table_create Logs_20170315 TABLE_NO_KEY column_create Logs_20170315 timestamp COLUMN_SCALAR Time column_create Logs_20170315 price COLUMN_SCALAR UInt32 column_create Logs_20170315 item COLUMN_SCALAR ShortText table_create Logs_20170316 TABLE_NO_KEY column_create Logs_20170316 timestamp COLUMN_SCALAR Time column_create Logs_20170316 price COLUMN_SCALAR UInt32 column_create Logs_20170316 item COLUMN_SCALAR ShortText table_create Logs_20170317 TABLE_NO_KEY column_create Logs_20170317 timestamp COLUMN_SCALAR Time column_create Logs_20170317 price COLUMN_SCALAR UInt32 column_create Logs_20170317 item COLUMN_SCALAR ShortText load --table Logs_20170315 [ {"timestamp": "2017/03/15 10:00:00", "price": 1000, "item": "A"}, {"timestamp": "2017/03/15 11:00:00", "price": 900, "item": "A"}, {"timestamp": "2017/03/15 12:00:00", "price": 300, "item": "B"}, {"timestamp": "2017/03/15 13:00:00", "price": 200, "item": "B"} ] load --table Logs_20170316 [ {"timestamp": "2017/03/16 10:00:00", "price": 530, "item": "A"}, {"timestamp": "2017/03/16 11:00:00", "price": 520, "item": "B"}, {"timestamp": "2017/03/16 12:00:00", "price": 110, "item": "A"}, {"timestamp": "2017/03/16 13:00:00", "price": 410, "item": "A"}, {"timestamp": "2017/03/16 14:00:00", "price": 710, "item": "B"} ] load --table Logs_20170317 [ {"timestamp": "2017/03/17 10:00:00", "price": 800, "item": "A"}, {"timestamp": "2017/03/17 11:00:00", "price": 400, "item": "B"}, {"timestamp": "2017/03/17 12:00:00", "price": 500, "item": "B"}, {"timestamp": "2017/03/17 13:00:00", "price": 300, "item": "A"} ] table_create Times TABLE_PAT_KEY Time column_create Times logs_20170315 COLUMN_INDEX Logs_20170315 timestamp column_create Times logs_20170316 COLUMN_INDEX Logs_20170316 timestamp column_create Times logs_20170317 COLUMN_INDEX Logs_20170317 timestamp logical_range_filter Logs \ --shard_key timestamp \ --filter 'price >= 300' \ --limit -1 \ --columns[offsetted_timestamp].stage filtered \ --columns[offsetted_timestamp].type Time \ --columns[offsetted_timestamp].flags COLUMN_SCALAR \ --columns[offsetted_timestamp].value 'timestamp - 39600000000' \ --columns[offsetted_day].stage filtered \ --columns[offsetted_day].type Time \ --columns[offsetted_day].flags COLUMN_SCALAR \ --columns[offsetted_day].value 'time_classify_day(offsetted_timestamp)' \ --columns[n_records_per_day_and_item].stage filtered \ --columns[n_records_per_day_and_item].type UInt32 \ --columns[n_records_per_day_and_item].flags COLUMN_SCALAR \ --columns[n_records_per_day_and_item].value 'window_count()' \ --columns[n_records_per_day_and_item].window.group_keys 'offsetted_day,item' \ --output_columns "_id,time_format_iso8601(offsetted_day),item,n_records_per_day_and_item" [ [ 0, 0.0, 0.0 ], [ [ [ "_id", "UInt32" ], [ "time_format_iso8601", null ], [ "item", "ShortText" ], [ "n_records_per_day_and_item", "UInt32" ] ], [ 1, "2017-03-14T00:00:00.000000+09:00", "A", 1 ], [ 2, "2017-03-15T00:00:00.000000+09:00", "A", 2 ], [ 3, "2017-03-15T00:00:00.000000+09:00", "B", 1 ], [ 1, "2017-03-15T00:00:00.000000+09:00", "A", 2 ], [ 2, "2017-03-16T00:00:00.000000+09:00", "B", 2 ], [ 4, "2017-03-16T00:00:00.000000+09:00", "A", 2 ], [ 5, "2017-03-16T00:00:00.000000+09:00", "B", 2 ], [ 1, "2017-03-16T00:00:00.000000+09:00", "A", 2 ], [ 2, "2017-03-17T00:00:00.000000+09:00", "B", 2 ], [ 3, "2017-03-17T00:00:00.000000+09:00", "B", 2 ], [ 4, "2017-03-17T00:00:00.000000+09:00", "A", 1 ] ] ]
この機能には、まだリリースされていない、Apache Arrow 3.0.0が必要です。
参照カラムに対する検索でシーケンシャルサーチをサポートしました。
この機能は、インデックス検索でたくさんのレコードがマッチした場合、かつ結果セットが十分小さい場合にのみ使われます。
上記のケースでは、インデックス検索よりもシーケンシャルサーチの方が速いためです。
この機能はデフォルトでは無効です。
この機能は、環境変数
GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO_REFERENCE
を設定することで有効になります。環境変数
GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO_REFERENCE
はインデックス検索からシーケンシャルサーチに切り替えるためのしきい値です。例えば、以下のように
GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO_REFERENCE=0.7
とセットした場合、結果セットのレコード数が、総レコード数の70%以下の場合にシーケンシャルサーチで検索します。$ export GRN_II_SELECT_TOO_MANY_INDEX_MATCH_RATIO_REFERENCE=0.7 table_create Tags TABLE_HASH_KEY ShortText table_create Memos TABLE_HASH_KEY ShortText column_create Memos tag COLUMN_SCALAR Tags load --table Memos [ {"_key": "Rroonga is fast!", "tag": "Rroonga"}, {"_key": "Groonga is fast!", "tag": "Groonga"}, {"_key": "Mroonga is fast!", "tag": "Mroonga"}, {"_key": "Groonga sticker!", "tag": "Groonga"}, {"_key": "Groonga is good!", "tag": "Groonga"} ] column_create Tags memos_tag COLUMN_INDEX Memos tag select Memos --query '_id:>=3 tag:@Groonga' --output_columns _id,_score,_key,tag [ [ 0, 0.0, 0.0 ], [ [ [ 2 ], [ [ "_id", "UInt32" ], [ "_score", "Int32" ], [ "_key", "ShortText" ], [ "tag", "Tags" ] ], [ 4, 2, "Groonga sticker!", "Groonga" ], [ 5, 2, "Groonga is good!", "Groonga" ] ] ] ]
[tokenizers]
TokenDocumentVectorTFIDF
とTokenDocumentVectorBM25
でトークンカラムをサポートしました。インデックスカラムと同じソースを持つトークンカラムがある場合、これらのトークナイザーは、トークンカラムのトークンIDを使います。
トークンカラムは、既にトークナイズ済みのデータを持っています。
そのため、トークンカラムを使うことによって、これらのトークナイザーのパフォーマンスが改善されます。
例えば、以下のように、
content_tokens
というトークンカラムを作ることで、この機能を使えます。table_create Memos TABLE_NO_KEY column_create Memos content COLUMN_SCALAR Text load --table Memos [ {"content": "a b c a"}, {"content": "c b c"}, {"content": "b b a"}, {"content": "a c c"}, {"content": "a"} ] table_create Tokens TABLE_PAT_KEY ShortText \ --normalizer NormalizerNFKC121 \ --default_tokenizer TokenNgram column_create Tokens memos_content COLUMN_INDEX|WITH_POSITION Memos content column_create Memos content_tokens COLUMN_VECTOR Tokens content table_create DocumentVectorBM25 TABLE_HASH_KEY Tokens \ --default_tokenizer \ 'TokenDocumentVectorBM25("index_column", "memos_content", \ "df_column", "df")' column_create DocumentVectorBM25 df COLUMN_SCALAR UInt32 column_create Memos content_feature COLUMN_VECTOR|WITH_WEIGHT|WEIGHT_FLOAT32 \ DocumentVectorBM25 content select Memos [ [ 0, 0.0, 0.0 ], [ [ [ 5 ], [ [ "_id", "UInt32" ], [ "content", "Text" ], [ "content_feature", "DocumentVectorBM25" ], [ "content_tokens", "Tokens" ] ], [ 1, "a b c a", { "a": 0.5095787, "b": 0.6084117, "c": 0.6084117 }, [ "a", "b", "c", "a" ] ], [ 2, "c b c", { "c": 0.8342565, "b": 0.5513765 }, [ "c", "b", "c" ] ], [ 3, "b b a", { "b": 0.9430448, "a": 0.3326656 }, [ "b", "b", "a" ] ], [ 4, "a c c", { "a": 0.3326656, "c": 0.9430448 }, [ "a", "c", "c" ] ], [ 5, "a", { "a": 1.0 }, [ "a" ] ] ] ] ]
TokenDocumentVectorTFIDF
とTokenDocumentVectorBM25
は、各トークンに対して重みをつけます。TokenDocumentVectorTFIDF
は、TF-IDFを使ってトークンの重みを計算します。TF-IDFについては、 https://radimrehurek.com/gensim/models/tfidfmodel.html を参照してください。
TokenDocumentVectorBM25
は、Okapi BM25を使ってトークンの重みを計算します。Okapi BM25については、 https://en.wikipedia.org/wiki/Okapi_BM25 を参照してください。
以下のケースのパフォーマンスを改善しました。
(column @ "value") && (column @ "value")
[Ubuntu] Ubuntu 20.10 (Groovy Gorilla)をサポートしました。
[Debian GNU/Linux] stretchのサポートをやめました。
EOLになったためです。
[CentOS] CentOS 6のサポートをやめました。
EOLになったためです。
[httpd] バンドルしているnginxのバージョンを1.19.6に更新しました。
修正#
以下のように、複数のドリルダウンのキーと複数のアクセサーを使用した時にGroongaがクラッシュする問題を修正しました。[GitHub#1153][naoaさんがパッチ提供]
table_create Tags TABLE_PAT_KEY ShortText table_create Memos TABLE_HASH_KEY ShortText column_create Memos tags COLUMN_VECTOR Tags column_create Memos year COLUMN_SCALAR Int32 load --table Memos [ {"_key": "Groonga is fast!", "tags": ["full-text-search"], "year": 2019}, {"_key": "Mroonga is fast!", "tags": ["mysql", "full-text-search"], "year": 2019}, {"_key": "Groonga sticker!", "tags": ["full-text-search", "sticker"], "year": 2020}, {"_key": "Rroonga is fast!", "tags": ["full-text-search", "ruby"], "year": 2020}, {"_key": "Groonga is good!", "tags": ["full-text-search"], "year": 2020} ] select Memos \ --filter '_id > 0' \ --drilldowns[tags].keys 'tags,year >= 2020' \ --drilldowns[tags].output_columns _key[0],_key[1],_nsubrecs select Memos \ --filter '_id > 0' \ --drilldowns[tags].keys 'tags,year >= 2020' \ --drilldowns[tags].output_columns _key[1],_nsubrecs
以下のように、同じフレーズが複数回出現すると、近傍フレーズ検索がマッチしない問題を修正しました。
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": "a x a x b x x"}, {"content": "a x x b x"} ] select Entries \ --match_columns content \ --query '*NP2"a b"' \ --output_columns '_score, content'
感謝#
Hung Nguyen Vさん
naoaさん
timgates42さん [GitHub#1155にてパッチ提供]
10.0.9リリース - 2020-12-01#
改良#
limit
に-1
を指定した時のパフォーマンスを改善しました。[reference_acquire] 新しいオプション
--auto_release_count
を追加しました。Groongaは、リクエストが
--auto_release_count
で指定された値に到達した時に自動的に参照カウントを減らします。例えば、以下のように、取得した
User
の参照は、2番目のstatus
が処理された後に自動的に解放されます。reference_acquire --target_name Users --auto_release_count 2 status # Users is still referred. status # Users' reference is released after this command is processed.
このオプションで、取得した参照の解放漏れを防げます。
Groongaが空の
vector
やuvector
を評価した時の動作を変更しました。空の
vector
とuvector
はcommand version 3では、false
と評価されます。この挙動はcommand version 3でのみ有効です。
今までとは挙動が異なることに注意してください。
[ノーマライザー] Unicode 13.0 の NFKC(Normalization Form Compatibility Composition)をベースにしたノーマライザー
NormalizerNFKC130
を追加しました。[トークンフィルター] Unicode 13.0 の NFKC(Normalization Form Compatibility Composition)をベースにしたトークンフィルター
TokenFilterNFKC130
を追加しました。[select]
"_score = column - X"
のパフォーマンスを改善しました。[reference_acquire]
--recursive dependent
オプションを指定した時に必要のないインデックスカラムへの参照を取得しないように改善しました。今回のリリースから、
--recursive dependent
の対象は、対象のテーブルのキーあるいはデータカラムに設定してあるインデックスカラムです。
[select] 順序限定の近傍フレーズ検索をサポートしました。
今までの近傍フレーズ検索は、指定したフレーズ間の距離が近いレコードのみを探していました。
この機能は、以下の条件を満たすレコードを探します。
指定したフレーズ間の距離が近い場合。
指定したフレーズが指定した順序で並んでいる場合。
この機能は、
*ONP
を演算子として使います。(*NP
演算子ではないことに注意してください。)$
はクエリー構文では、$
そのものとして扱います。クエリー構文では、$
は特殊文字ではないことに注意してください。スクリプト構文の場合、この機能は以下のように使用します。
table_create Entries TABLE_NO_KEY column_create Entries content COLUMN_SCALAR Text table_create Terms TABLE_PAT_KEY ShortText \ --default_tokenizer 'TokenNgram("unify_alphabet", false, \ "unify_digit", false)' \ --normalizer NormalizerNFKC121 column_create Terms entries_content COLUMN_INDEX|WITH_POSITION Entries content load --table Entries [ {"content": "abcXYZdef"}, {"content": "abebcdXYZdef"}, {"content": "abcdef"}, {"content": "defXYZabc"}, {"content": "XYZabc"}, {"content": "abc123456789def"}, {"content": "abc12345678def"}, {"content": "abc1de2def"} ] select Entries --filter 'content *ONP "abc def"' --output_columns '_score, content' [ [ 0, 0.0, 0.0 ], [ [ [ 4 ], [ [ "_score", "Int32" ], [ "content", "Text" ] ], [ 1, "abcXYZdef" ], [ 1, "abcdef" ], [ 1, "abc12345678def" ], [ 1, "abc1de2def" ] ] ] ]
クエリー構文の場合、この機能は以下のように使用します。
select Entries --query 'content:*ONP "abc def"' --output_columns '_score, content' [ [ 0, 0.0, 0.0 ], [ [ [ 4 ], [ [ "_score", "Int32" ], [ "content", "Text" ] ], [ 1, "abcXYZdef" ], [ 1, "abcdef" ], [ 1, "abc12345678def" ], [ 1, "abc1de2def" ] ] ] ]
[httpd] バンドルしているnginxのバージョンを1.19.5に更新しました。
修正#
[Groonga HTTPサーバー] Groonga HTTP server が全てのワーカースレッドの完全な終了を待たずに終了していた問題を修正しました。
今まで、Groonga HTTP server は、ワーカースレッドの処理が終了した後から、自身の終了処理を開始していました。しかし、このタイミングでは、ワーカースレッドは完全に終了していないことがあります。そのため、タイミングによってはGroonga HTTP serverがクラッシュすることがあります。Groonga HTTP server がワーカースレッドがまだ使用している領域を解放することがあるためです。
10.0.8リリース - 2020-10-29#
改良#
[select] 大きいサイズのドリルダウンのキーを使えるようになりました。
Groongaのテーブルのキーサイズの最大は4KiBですが、複数のドリルダウンのキーを指定している場合、ドリルダウンのキーのサイズが4KiBを超える場合があります。
例えば、以下のケースで、
tag
キーとn_like
キーのトータルサイズが4KiB以上だった場合、ドリルダウンは失敗します。
select Entries \ --limit -1 \ --output_columns tag,n_likes \ --drilldowns[tag.n_likes].keys tag,n_likes \ --drilldowns[tag.n_likes].output_columns _value.tag,_value.n_likes,_nsubrecs
ドリルダウンは指定されている全てのキーを連結しているためです。そのため、ドリルダウンのキーそれぞれが大きい場合は、ドリルダウンのキーを連結したサイズが4KiB以上になります。
この機能には、 xxHash が必要です。
ただ、Groongaをパッケージからインストールしている場合は、特に何もしなくてもこの機能を使えます。Groongaのパッケージには、すでに xxHash が含まれているためです。
[select] 異なるテーブルを参照しているカラムを同じ動的カラムで扱えるようにしました。
従来、異なるテーブルを参照しているカラムは、同一の動的カラムでは扱えませんでした。カラムの型が異なるためです。
今回のバージョンから、以下のように異なるテーブルを参照しているカラムであってもビルトインの型にキャストすることで同じ動的カラムで扱うことができます。
table_create Store_A TABLE_HASH_KEY ShortText table_create Store_B TABLE_HASH_KEY ShortText table_create Customers TABLE_HASH_KEY Int32 column_create Customers customers_A COLUMN_VECTOR Store_A column_create Customers customers_B COLUMN_VECTOR Store_B load --table Customers [ {"_key": 1604020694, "customers_A": ["A", "B", "C"]}, {"_key": 1602724694, "customers_B": ["Z", "V", "Y", "T"]}, ] select Customers \ --filter '_key == 1604020694' \ --columns[customers].stage output \ --columns[customers].flags COLUMN_VECTOR \ --columns[customers].type ShortText \ --columns[customers].value 'customers_A' \ --output_columns '_key, customers'
今までは、
Store_A
またはStore_B
をcustomers
カラムのtype
に設定する必要がありました。上記の例では、
customers_A
カラムの型は、ShortText
にキャストします。customers_A
のキーもcustomers_B
のキーもShortText
型であるため、これでcustomers
カラムの値にcustomers_B
の値も設定できます。
[select] 検索結果のレコード数が非常に多い場合のパフォーマンスを改善しました。
この最適化は、以下のケースで効果があります。
--filter 'column <= "value"'
or--filter 'column >= "value"'
--filter 'column == "value"'
--filter 'between(...)'
または--filter 'between(_key, ...)'
--filter 'sub_filter(reference_column, ...)'
--filter '_key > "value"'
のような_key
に対する比較--filter 'geo_in_circle(...)'
バンドルしているLZ4を1.8.2から1.9.2に更新しました。
xxHash 0.8 をサポートしました。
[httpd] バンドルしているnginxのバージョンを1.19.4に更新しました。
修正#
ブラウザーベースの管理ツール関連の問題を修正しました。 [GitHub#1139][sutaminさんの報告]
Groongaのロゴが表示されない問題。
日本語のインデックスページにスループットグラフが表示されない問題。
[between]
between(_key, ...)
が常にシーケンシャルサーチで評価される問題を修正しました。
感謝#
sutaminさん
10.0.7リリース - 2020-09-29#
改良#
[highlight], [highlight_full] ノーマライザーにオプションを指定できるようになりました。
[リターンコード] 新しいリターンコード
GRN_CONNECTION_RESET
を追加しました。このリターンコードは、リモートホストから強制的に接続を切断されたときに返されます。
Ubuntu 19.10(Eoan Ermine)のサポートをやめました。
このバージョンはEOLになっているためです。
[httpd] バンドルしているnginxのバージョンを1.19.2に更新しました。
[grndb] キーの重複を検出できるようになりました。
今回のリリースから、
grndb check
でキーの重複も検出できるようになりました。このチェックは、
TABLE_NO_KEY
のテーブル以外で有効です。grndb check
で重複が検出されたテーブルにインデックスカラムしかない場合は、grndb recover
で復旧できます。
[table_create], [column_create] 新しいオプション
--path
を追加しました。このオプションによって指定したテーブルまたは、カラムを任意のパスに格納できます。
このオプションは、高速なストレージ(SSDなど)によく使うテーブルやカラムを格納し、低速なストレージ(HDDなど)にあまり使わないテーブルやカラムを格納したいときに有用です。
このオプションは、相対パス、絶対パスの両方が指定できます。
相対パスを指定した場合は、
groonga
プロセスのパスを起点に指定したパスが解決されます。
--path
を指定した場合、dump
コマンドの結果に--path
の情報が含まれます。したがって、
--path
を指定した場合、 異なる環境のホストではリストアできなくなります。これは、ディレクトリ構成や
groonga
プロセスの場所が環境ごとに異なるためです。
--path
の情報をdump
に含みたくない場合は、dump
コマンド実行時に--dump_paths no
を指定する必要があります。
[dump] 新しいオプション
--dump_paths
を追加しました。--dump_paths
オプションは、--path
をダンプするかどうかを制御します。デフォルト値は
yes
です。もし、テーブルやカラム作成時に
--path
を指定していて、--path
の情報をdump
に含みたくない場合は、dump
コマンド実行時に--dump_paths
にno
を指定してください。
新しい関数
string_toknize()
を追加しました。この関数は、第二引数に指定されたカラムの値を、第一引数に指定されたトークナイザーでトークナイズします。
[tokenizers] 新しいトークナイザー
TokenDocumentVectorTFIDF
を追加しました。(実験的)このトークナイザーは、TF-IDFで文書ベクトルを自動で生成します。
[tokenizers] 新しいトークナイザー
TokenDocumentVectorBM25
を追加しました。(実験的)このトークナイザーは、BM25で文書ベクトルを自動で生成します。
[select] 同一センテンス内での、フレーズ近傍検索をサポートしました。
修正#
[load] 257個のカラムに対して
load
を実行するとload
の応答が返らなくなる問題を修正しました。この問題は、10.0.4以降で発生する可能性があります。
この問題は、
[a, b, c, ...]
の形式でデータをロードした時にのみ発生します。[{...}]
を使ってデータをロードした場合は発生しません。
[MessagePack] float32の値を正しくアンパックできない問題を修正しました。
マルチカラムインデックス関連の問題を修正しました。
_score
の値が壊れることがあります。ヒットしないはずのレコードがヒットすることがあります。
この問題の発生条件については、以下のURLを参照してください。
10.0.6リリース - 2020-08-29#
改良#
[logical_range_filter] 大きなデータの検索プランを改善しました。
通常、
logical_range_filter
はlogical_select
より高速ですが、以下のケースでは、logical_select
より遅くなっていました。logical_range_filter
には要求されたレコード数をなかなか見つけられない場合にシーケンシャル検索からインデックス検索に切り替える機能があります。(logical_range_filter
は通常、検索対象のレコード数が多い場合は、シーケンシャル検索を使います。)上記の切り替えが発生した場合は、
logical_select
と検索処理がほぼ同じになります。そのため、大きなデータを対象とした検索では、上記のケースで、logical_range_filter
は、logical_select
の数倍遅くなります。なぜなら、logical_range_filter
は検索後にソートを実行するためです。
今回のリリースから、大きなデータを検索する場合に、今までよりシーケンシャル検索が採用されやすくしました。
これによって、
logical_select
と同等の処理になるケースが減少しlogical_range_filter
のパフォーマンスが改善します。
[httpd] バンドルしているnginxのバージョンを1.19.1に更新しました。
Debian GNU/Linux へのインストール方法を変更しました。
groonga-archive-keyring
の代わりにgroonga-apt-source
を使うように変更しました。lintian
コマンドが/etc/apt/sources.lists.d/
配下にファイルを置くパッケージはapt-source
を使うよう推奨しているためです。lintian
コマンドはパッケージングに共通のエラーをチェックするためのコマンドです。インストール方法についての詳細は、以下のURLも参照してください。
[logical_select]
highlight_html
とhighlight_full
をサポートしました。値を持たない配列を削除した時、そのレコードのIDを再利用するようにしました。[GitHub#mroonga/mroonga#327][gaeeyoさんの報告]
値を持たない配列を削除した場合、削除されたIDは再利用されません。
Groongaは大きなIDがあることによって、多くのストレージを使用します。大きなIDはそれだけで、多くのストレージを使うためです。
大きなIDは、例えば、Mroongaの
mroonga_operations
のように多くの追加と削除によって発生します。
[select] インデックスを設定していない全文検索のパフォーマンスを改善しました。
[関数] 全ての引数が他のテーブルへの参照か、リテラルである関数のパフォーマンスを改善しました。
[インデックス構築] トークンカラムを使った静的インデックス構築のパフォーマンスを改善しました。 [GitHub#1126][naoaさんがパッチ提供]
"_score = func(...)"
のパフォーマンスを改善しました。_score
の値が"_score = func(...)"
のように関数によってのみ算出される場合のパフォーマンスを改善しました。
修正#
応答送信のエラーが発生した後の応答にゴミが含まれることがある問題を修正しました。
これは、クライアントが全ての応答を読み込まずにコネクションがクローズされた場合に発生することがあります。
感謝#
gaeeyoさん
naoaさん
10.0.5リリース - 2020-07-30#
改良#
[select]
-load_table
で指定したテーブルに参照を格納できるようにしました。--load-table
は予め用意したテーブルに検索結果を格納する機能です。複数回検索が実行される場合、このテーブルに結果を格納することで、検索結果をキャッシュできます。
このテーブルを使うことで、初回以降の検索時間を短縮できます。
今回のリリース以降で、以下のようにこのテーブルに別のテーブルへの参照を格納できます。
カラムの値を格納せず、参照のみを格納するため、このテーブルのサイズを小さくすることができます。
このテーブルに対して検索する場合、参照先のテーブルのインデックスを使って検索できます。
table_create Logs TABLE_HASH_KEY ShortText column_create Logs timestamp COLUMN_SCALAR Time table_create Times TABLE_PAT_KEY Time column_create Times logs_timestamp COLUMN_INDEX Logs timestamp table_create LoadedLogs TABLE_HASH_KEY Logs load --table Logs [ { "_key": "2015-02-03:1", "timestamp": "2015-02-03 10:49:00" }, { "_key": "2015-02-03:2", "timestamp": "2015-02-03 12:49:00" }, { "_key": "2015-02-04:1", "timestamp": "2015-02-04 00:00:00" } ] select \ Logs \ --load_table LoadedLogs \ --load_columns "_key" \ --load_values "_key" \ --limit 0 select \ --table LoadedLogs \ --filter 'timestamp >= "2015-02-03 12:49:00"' [ [ 0, 0.0, 0.0 ], [ [ [ 2 ], [ [ "_id", "UInt32" ], [ "_key", "ShortText" ], [ "timestamp", "Time" ] ], [ 2, "2015-02-03:2", 1422935340.0 ], [ 3, "2015-02-04:1", 1422975600.0 ] ] ] ]
[select] 以下のケースのソートのパフォーマンスを改善しました。
多くのソートキーがID解決をする場合。
例えば、以下の式はIDを解決する必要があります。
--filter true --sort_keys column
例えば、以下の式はIDを解決する必要がありません。 擬似カラム
_score
は、結果テーブルに存在しており、ソーステーブルには存在しないためIDを解決する必要がありません。--filter true --sort_keys _score
ソート対象のテーブルがキーを持っている場合。
したがって、
TABLE_NO_KEY
はこの改善をサポートしていません。
[select] 以下のケースのパフォーマンスを少し改善しました。
沢山のレコードがマッチする検索をしているケース。
沢山のレコードに対してドリルダウンするケース。
[aggregator] score アクセサーをサポートしました。[GitHub#1120][naoaさんのパッチ提供]
例えば、 以下のように
_score
をaggregator_*
の対象にできます。table_create Items TABLE_HASH_KEY ShortText column_create Items price COLUMN_SCALAR UInt32 column_create Items tag COLUMN_SCALAR ShortText load --table Items [ {"_key": "Book", "price": 1000, "tag": "A"}, {"_key": "Note", "price": 1000, "tag": "B"}, {"_key": "Box", "price": 500, "tag": "B"}, {"_key": "Pen", "price": 500, "tag": "A"}, {"_key": "Food", "price": 500, "tag": "C"}, {"_key": "Drink", "price": 300, "tag": "B"} ] select Items \ --filter true \ --drilldowns[tag].keys tag \ --drilldowns[tag].output_columns _key,_nsubrecs,score_mean \ --drilldowns[tag].columns[score_mean].stage group \ --drilldowns[tag].columns[score_mean].type Float \ --drilldowns[tag].columns[score_mean].flags COLUMN_SCALAR \ --drilldowns[tag].columns[score_mean].value 'aggregator_mean(_score)' [ [ 0, 0.0, 0.0 ], [ [ [ 6 ], [ [ "_id", "UInt32" ], [ "_key", "ShortText" ], [ "price", "UInt32" ], [ "tag", "ShortText" ] ], [ 1, "Book", 1000, "A" ], [ 2, "Note", 1000, "B" ], [ 3, "Box", 500, "B" ], [ 4, "Pen", 500, "A" ], [ 5, "Food", 500, "C" ], [ 6, "Drink", 300, "B" ] ], { "tag": [ [ 3 ], [ [ "_key", "ShortText" ], [ "_nsubrecs", "Int32" ], [ "score_mean", "Float" ] ], [ "A", 2, 1.0 ], [ "B", 3, 1.0 ], [ "C", 1, 1.0 ] ] } ] ]
[インデックス構築] VC++版の静的インデックス構築のパフォーマンスを改善しました。
[select] JSON形式で出力する際に
NaN
やInfinity
、-Infinity
の代わりにnull
を出力するようにしました。これらの値はJSONではサポートされていないためです。
[select] 標準偏差の集計をサポートしました。
例えば、以下のようにグループごとの標準偏差を計算できます。
table_create Items TABLE_HASH_KEY ShortText column_create Items price COLUMN_SCALAR UInt32 column_create Items tag COLUMN_SCALAR ShortText load --table Items [ {"_key": "Book", "price": 1000, "tag": "A"}, {"_key": "Note", "price": 1000, "tag": "B"}, {"_key": "Box", "price": 500, "tag": "B"}, {"_key": "Pen", "price": 500, "tag": "A"}, {"_key": "Food", "price": 500, "tag": "C"}, {"_key": "Drink", "price": 300, "tag": "B"} ] select Items \ --drilldowns[tag].keys tag \ --drilldowns[tag].output_columns _key,_nsubrecs,price_sd \ --drilldowns[tag].columns[price_sd].stage group \ --drilldowns[tag].columns[price_sd].type Float \ --drilldowns[tag].columns[price_sd].flags COLUMN_SCALAR \ --drilldowns[tag].columns[price_sd].value 'aggregator_sd(price)' \ --output_pretty yes [ [ 0, 1594339851.924836, 0.002813816070556641 ], [ [ [ 6 ], [ [ "_id", "UInt32" ], [ "_key", "ShortText" ], [ "price", "UInt32" ], [ "tag", "ShortText" ] ], [ 1, "Book", 1000, "A" ], [ 2, "Note", 1000, "B" ], [ 3, "Box", 500, "B" ], [ 4, "Pen", 500, "A" ], [ 5, "Food", 500, "C" ], [ 6, "Drink", 300, "B" ] ], { "tag": [ [ 3 ], [ [ "_key", "ShortText" ], [ "_nsubrecs", "Int32" ], [ "price_sd", "Float" ] ], [ "A", 2, 250.0 ], [ "B", 3, 294.3920288775949 ], [ "C", 1, 0.0 ] ] } ] ]
aggregate_sd(target, {"unbiased": true})
と指定することで、不偏標準偏差も計算できます。
[Windows] Visual Studio 2013のサポートをやめました。
修正#
[Groonga HTTPサーバー] 応答がエラーで中断された時に、
shutdown?immediate
を実行しても、リクエストが中断しない問題を修正しました。リクエスト中にエラーが発生した時にクラッシュする問題を修正しました。
これは、Apache Arrow形式を使っている時にのみ発生します。
前のリクエストがエラーによって中断された後に再度Groongaへリクエストを送信した時にGroongaがクラッシュします。
[between] 一時テーブルを使用した時にクラッシュする問題を修正しました。
例えば、
between
の第一引数に動的カラムを指定すると、Groongaがクラッシュしていました。
プラグインで作成したプロシージャーが予期せず解放される問題を修正しました。
参照カウントモードでのみ発生します。
plugin_register
を使っていない場合は、発生しません。plugin_register
を実行したプロセスでは発生しません。plugin_register
を実行していないプロセスで発生します。
token_column
を使った静的インデックス構築中に正規化エラーが発生する問題を修正しました。[GitHub#1122][naoaさんの報告]
感謝#
naoaさん
10.0.4リリース - 2020-06-29#
改良#
[テーブル] ハッシュテーブルで4億件のレコードの登録をサポートしました。
[select]
_score
が再帰的に値を取得しない時のパフォーマンスを改善しました。Groongaは、検索結果が検索対象の時に、
_score
の値を再帰的に取得します。例えば、
slices
は検索結果が検索対象です。したがって、slices
を使っているクエリーでは、この改善は効果がありません。
[ログ] ドリルダウンのキーをクエリーログに出力するようにしました。
[reference_acquire], [reference_release] 参照カウントモード用に新しいコマンドを追加しました。
短い間隔で複数の
load
を呼び出す必要がある場合、参照カウントモードによる自動クローズによってパフォーマンスが低下します。複数の
load
の前に/reference_acquire
を呼び、 複数のload
の後に/reference_release
を呼ぶことで、このパフォーマンスの低下を避けることができます。/reference_acquire
と/reference_release
の間は自動クローズは無効になります。/reference_acquire
が、対象のオブジェクトの参照を取得するためです。
パフォーマンスに影響のある操作が完了したら、
/reference_release
を呼ぶ必要があります。/reference_release
を呼ばない場合、参照カウントモードは機能しません。
[select] 一度の
drilldown
で複数グループの集計をサポートしました。以下のように、一回の
drilldown
で異なるグループ毎に和と算術平均を計算できるようになりました。table_create Items TABLE_HASH_KEY ShortText column_create Items price COLUMN_SCALAR UInt32 column_create Items quantity COLUMN_SCALAR UInt32 column_create Items tag COLUMN_SCALAR ShortText load --table Items [ {"_key": "Book", "price": 1000, "quantity": 100, "tag": "A"}, {"_key": "Note", "price": 1000, "quantity": 10, "tag": "B"}, {"_key": "Box", "price": 500, "quantity": 15, "tag": "B"}, {"_key": "Pen", "price": 500, "quantity": 12, "tag": "A"}, {"_key": "Food", "price": 500, "quantity": 111, "tag": "C"}, {"_key": "Drink", "price": 300, "quantity": 22, "tag": "B"} ] select Items \ --drilldowns[tag].keys tag \ --drilldowns[tag].output_columns _key,_nsubrecs,price_sum,quantity_sum \ --drilldowns[tag].columns[price_sum].stage group \ --drilldowns[tag].columns[price_sum].type UInt32 \ --drilldowns[tag].columns[price_sum].flags COLUMN_SCALAR \ --drilldowns[tag].columns[price_sum].value 'aggregator_sum(price)' \ --drilldowns[tag].columns[quantity_sum].stage group \ --drilldowns[tag].columns[quantity_sum].type UInt32 \ --drilldowns[tag].columns[quantity_sum].flags COLUMN_SCALAR \ --drilldowns[tag].columns[quantity_sum].value 'aggregator_sum(quantity)' [ [ 0, 0.0, 0.0 ], [ [ [ 6 ], [ [ "_id", "UInt32" ], [ "_key", "ShortText" ], [ "price", "UInt32" ], [ "quantity", "UInt32" ], [ "tag", "ShortText" ] ], [ 1, "Book", 1000, 100, "A" ], [ 2, "Note", 1000, 10, "B" ], [ 3, "Box", 500, 15, "B" ], [ 4, "Pen", 500, 12, "A" ], [ 5, "Food", 500, 111, "C" ], [ 6, "Drink", 300, 22, "B" ] ], { "tag": [ [ 3 ], [ [ "_key", "ShortText" ], [ "_nsubrecs", "Int32" ], [ "price_sum", "UInt32" ], [ "quantity_sum", "UInt32" ] ], [ "A", 2, 1500, 112 ], [ "B", 3, 1800, 47 ], [ "C", 1, 500, 111 ] ] } ] ]
[groonga-httpd] スタンドアローンモードで、
--pid-path
をサポートしました。以前のバージョンのスタンドアローンモードでは、
--pid-path
は無視されていました。
[io_flush] 参照カウントモードに対応しました。
[logical_range_filter],[logical_count] 参照カウントモードに対応しました。
[Groonga HTTPサーバー] 最後のチャンクの後にヘッダーをつけないようにしました。
最後のチャンクの後のヘッダーを無視するHTTPクライアントが存在する可能性があるためです。
[vector_slice]
Float32
型のベクターをサポートしました。 [GitHub#1106 naoaさんがパッチ提供]トークンカラムを使った、並列静的インデックス構築をサポートしました。
予めトークナイズされたデータから複数スレッドで静的インデックスの構築ができるようになりました。
以下の環境変数で、並列静的インデックス構築のパラメータを調整できます。
GRN_TOKEN_COLUMN_PARALLEL_CHUNK_SIZE
: スレッド毎にどのくらいのレコードを処理するかを指定します。デフォルト値は
1024
レコードです。
GRN_TOKEN_COLUMN_PARALLEL_TABLE_SIZE_THRESHOLD
: どのくらいのソースレコードで並列化するかを指定します。デフォルト値は
102400
レコードです。
[select] 参照カウントモード時の
load_table
のパフォーマンスを改善しました。
修正#
シャードをまたいでいて、かつ
--filter
を指定していない動的カラムを使って検索すると、Gronngaのデータベースが破損する問題を修正しました。schema
コマンドの結果にFloat32
型が表示されなかった問題を修正しました。参照
uvector
が要素を持っていないとき、_nsubrecs
を余分にカウントする問題を修正しました。
感謝#
naoaさん
10.0.3リリース - 2020-05-29#
改良#
予めトークナイズされたデータから転置インデックスを構築できるようになりました。
これにより、インデックスの構築が高速化します。
この改善を使うには、トークンカラムを準備する必要があります。
トークンカラムは、インデックスカラムのように自動で値が生成されます。
トークンカラムの値はソースカラムの値をトークナイズすることで生成されます。
トークンカラムは以下のようにソースカラムを設定することで作成できます。
table_create Terms TABLE_PAT_KEY ShortText \ --normalizer NormalizerNFKC121 \ --default_tokenizer TokenNgram table_create Notes TABLE_NO_KEY column_create Notes title COLUMN_SCALAR Text # The last "title" is the source column. column_create Notes title_terms COLUMN_VECTOR Terms title
[select] 関数の引数に
vector
を指定できるようになりました。例えば、
query
のflags
オプションをvector
を使って以下のように記述できます。select \ --table Memos \ --filter 'query("content", "-content:@mroonga", \ { \ "expander": "QueryExpanderTSV", \ "flags": ["ALLOW_LEADING_NOT", "ALLOW_COLUMN"] \ })'
[select] 動的カラムに新しいステージ
result_set
を追加しました。このステージは、結果セットのテーブルにカラムを作ります。したがって、
query
かfilter
が存在しない場合は作られません。query
やfilter
が存在しない場合は、結果セットのテーブルが作られないためです。
このステージでは
_value
は使用できません。result_set
ステージの値はscore_column
に格納されます。
[vector_slice] 重み付きベクターの重みに
Float32
型が使えるようになりました。 [GitHub#1106 naoaさんがパッチ提供][select] drilldownsの動的カラムのステージに
filtered
とoutput
を追加しました。 [GitHub#1101 naoaさんがパッチ提供][GitHub#1100 naoaさんがパッチ提供]drilldowns[Label].stage filtered
やdrilldowns[Label].stage output
のように drilldowns の動的カラムのステージにfiltered
とoutput
を使えます。
[select] ドリルダウンでの集計に
Float
型の値をサポートしました。MAX
、MIN
、SUM
を使ってFloat
型の値の最大値、最小値、合計値を集計できます。
[query] [geo_in_rectangle] [geo_in_circle]
query()
とgeo_in_rectangle()
とgeo_in_circle()
に新しいオプションscore_column
を追加しました。score_column
を使うことで条件毎にスコアの値を格納できます。通常、Groongaは、全ての条件のスコアーを加算してスコアーを計算しますが、条件毎にスコアーの値を取得したいこともあります。
例えば以下のように、中心座標にどれだけ近いかをスコアーとして使いたい場合に
score_column
が使えます。
table_create LandMarks TABLE_NO_KEY column_create LandMarks name COLUMN_SCALAR ShortText column_create LandMarks category COLUMN_SCALAR ShortText column_create LandMarks point COLUMN_SCALAR WGS84GeoPoint table_create Points TABLE_PAT_KEY WGS84GeoPoint column_create Points land_mark_index COLUMN_INDEX LandMarks point load --table LandMarks [ {"name": "Aries" , "category": "Tower" , "point": "11x11"}, {"name": "Taurus" , "category": "Lighthouse", "point": "9x10" }, {"name": "Gemini" , "category": "Lighthouse", "point": "8x8" }, {"name": "Cancer" , "category": "Tower" , "point": "12x12"}, {"name": "Leo" , "category": "Tower" , "point": "11x13"}, {"name": "Virgo" , "category": "Temple" , "point": "22x10"}, {"name": "Libra" , "category": "Tower" , "point": "14x14"}, {"name": "Scorpio" , "category": "Temple" , "point": "21x9" }, {"name": "Sagittarius", "category": "Temple" , "point": "43x12"}, {"name": "Capricorn" , "category": "Tower" , "point": "33x12"}, {"name": "Aquarius" , "category": "mountain" , "point": "55x11"}, {"name": "Pisces" , "category": "Tower" , "point": "9x9" }, {"name": "Ophiuchus" , "category": "mountain" , "point": "21x21"} ] select LandMarks \ --sort_keys 'distance' \ --columns[distance].stage initial \ --columns[distance].type Float \ --columns[distance].flags COLUMN_SCALAR \ --columns[distance].value 0.0 \ --output_columns 'name, category, point, distance, _score' \ --limit -1 \ --filter 'geo_in_circle(point, "11x11", "11x1", {"score_column": distance}) && category == "Tower"' [ [ 0, 1590647445.406149, 0.0002503395080566406 ], [ [ [ 5 ], [ [ "name", "ShortText" ], [ "category","ShortText" ], [ "point", "WGS84GeoPoint" ], [ "distance", "Float" ], [ "_score", "Int32" ] ], [ "Aries", "Tower", "11x11", 0.0, 1 ], [ "Cancer", "Tower", "12x12", 0.0435875803232193, 1 ], [ "Leo", "Tower", "11x13", 0.06164214760065079, 1 ], [ "Pisces", "Tower", "9x9", 0.0871751606464386, 1 ], [ "Libra", "Tower", "14x14", 0.1307627409696579, 1 ] ] ] ]
上記の例では、
_score
によるソートは意味をなしません。category == "Tower"
によって、_score
の値は全て1
になるためです。しかし、socre_column
を使うことで、中心座標からの距離でソートできます。
[Windows] クラッシュしていないくてもエラー時にはバックトレースが出力されるようになりました。
[Windows] 古いWindowsのサポートをやめました。
10.0.3から、Windows 8 (Windows Server 2012) 以降を要求します。
[select] 参照可能なソートキーとそうでないソートキーが混在しているときのソートパフォーマンスを改善しました。
参照可能なソートキーとそうでないソートキーが混在していて、参照可能なキーが2つ以上あるときのソートパフォーマンスを改善しました。
参照可能なソートキーとは以下のソートキー以外のことです。
圧縮されたカラム
ドリルダウンのキーに複数の値が指定されているドリルダウンの値を格納する
_value
ShortText
型のキーを持たないパトリシアトライテーブルの_key
_score
文字列以外のソートキーが多いほど、ソートに使用するメモリ使用量が少なくなります。
[select] 全てのソートキーが参照可能なキーの時のソートのパフォーマンスを改善しました。
[select]
_socre = column1*X + column2*Y + ...
の場合のスコアラーのパフォーマンスを改善しました。この最適化は、
_score
内に多くの+
または*
がある場合に効きます。現状、
+
と*
に対してのみ効果があります。
[select] フレーズ近傍検索をサポートしました。
フレーズ単位で近傍検索できます。
フレーズ近傍検索のクエリー構文は、
*NP"Phrase1 phrase2 ..."
です。フレーズ近傍検索のスクリプト構文は、
column *NP "phrase1 phrase2 ..."
です。検索対象のフレーズにスペースを含む場合、 以下のようにフレーズを
"
で囲うことで検索できます。table_create Entries TABLE_NO_KEY column_create Entries content COLUMN_SCALAR Text table_create Terms TABLE_PAT_KEY ShortText \ --default_tokenizer 'TokenNgram("unify_alphabet", false, \ "unify_digit", false)' \ --normalizer NormalizerNFKC121 column_create Terms entries_content COLUMN_INDEX|WITH_POSITION Entries content load --table Entries [ {"content": "I started to use Groonga. It's very fast!"}, {"content": "I also started to use Groonga. It's also very fast! Really fast!"} ] select Entries --filter 'content *NP "\\"I started\\" \\"use Groonga\\""' --output_columns 'content' [ [ 0, 1590469700.715882, 0.03997230529785156 ], [ [ [ 1 ], [ [ "content", "Text" ] ], [ "I started to use Groonga. It's very fast!" ] ] ] ]
[ベクターカラム] 重み付きベクターの重みに
float32
型を追加しました。uint32
の代わりにfloat32
として重みを格納できます。この機能を使うには、
column_create
実行時にWEIGHT_FLOAT32
フラグを追加する必要があります。column_create Records tags COLUMN_VECTOR|WITH_WEIGHT|WEIGHT_FLOAT32 Tags
今の所、
WEIGHT_FLOAT32
フラグは、COLUMN_INDEX
フラグと併用できません。
以下のAPIを公開しました。
grn_obj_is_xxx
関数を追加しました。詳細は以下の通りです。grn_obj_is_weight_vector(grn_ctx *ctx, grn_obj *obj)
重み付きベクターかどうかを
bool
として返します。
grn_obj_is_uvector(grn_ctx *ctx, grn_obj *obj)
uvector
かどうかをbool
として返します。uvector
とは、要素のサイズが固定のvector
です。
grn_obj_is_weight_uvector(grn_ctx *ctx, grn_obj *obj)
重み付きuvectorかどうかを
bool
として返します。
grn_type_id_size(grn_ctx *ctx, grn_id id)
を追加しました。Groongaのデータ型のサイズを
size_t
として返します。
grn_selector_data_get_xxx
を追加しました。詳細は以下の通りです。これらの関数はセレクター関連のデータを返します。
これらの関数はセレクターの中で呼び出すことを想定しています。セレクター以外の場所で呼び出された場合は、
NULL
を返します。grn_selector_data_get(grn_ctx *ctx)
セレクター呼び出しに関する全ての情報を
grn_selector_data *
構造体として返します。
grn_selector_data_get_selector(grn_ctx *ctx, grn_selector_data *data)
セレクター自身を
grn_obj *
として返します。
grn_selector_data_get_expr(grn_ctx *ctx, grn_selector_data *data)
セレクターに使用されている、
--filter
条件や--query
条件をgrn_obj *
として返します。
grn_selector_data_get_table(grn_ctx *ctx, grn_selector_data *data)
検索対象のテーブルを
grn_obj *
として返します。
grn_selector_data_get_index(grn_ctx *ctx, grn_selector_data *data)
セレクターに使われているインデックスを
grn_obj *
として返します。
grn_selector_data_get_args(grn_ctx *ctx, grn_selector_data *data, size_t *n_args)
セレクターが呼び出した関数の引数を
grn_obj *
として返します。
grn_selector_data_get_result_set(grn_ctx *ctx, grn_selector_data *data)
結果テーブルを
grn_obj *
として返します。
grn_selector_data_get_op(grn_ctx *ctx, grn_selector_data *data)
既存の結果セットに対してどう集合演算したかを
grn_operator
として返します。
grn_plugin_proc_xxx
関数を追加しました。詳細は以下の通りです。grn_plugin_proc_get_value_operator(grn_ctx *ctx, grn_obj *value, grn_operator default_operator, const char *context)
クエリーオペレーターを
grn_operator
として返します。例えば、
&&
はGRN_OP_ANDP
として返されます。
grn_plugin_proc_get_value_bool(grn_ctx *ctx, grn_obj *value, bool default_value, const char *tag)
以下の関数の引数
with_transposition
のようにtrue
またはfalse
が指定される値をbool
として返します。(bool
はC言語のデータ型です。)fuzzy_search(column, query, {"max_distance": 1, "prefix_length": 0, "max_expansion": 0, "with_transposition": true})
grn_proc_options_xxx
関数を追加しました。詳細は以下の通りです。これらは、
query()
でのみ使えます。grn_proc_options_parsev(grn_ctx *ctx, grn_obj *options, const char *tag, const char *name, va_list args)
を追加しました。オプションのパースを実行します。
今までは、オプションのパースを自分で実装しなければなりませんでしたが、この関数を呼び出すだけでオプションをパースできます。
grn_proc_options_parse(grn_ctx *ctx, grn_obj *options, const char *tag, const char *name, ...)
grn_proc_option_parsev()
を呼び出します。したがって、この関数の機能は、grn_proc_options_parsev()
と同じです。grn_proc_options_parsev()
とは、インターフェースだけが異なります。
grn_text_printfv(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
を追加しました。grn_text_vprintf
は10.0.3から非推奨になりました。 代わりにgrn_text_printfv
を使ってください。
grn_type_id_is_float_family(grn_ctx *ctx, grn_id id)
を追加しました。grn_type_id
がGRN_DB_FLOAT32
またはGRN_DB_FLOAT
かどうかをbool
として返します。
grn_dat_cursor_get_max_n_records(grn_ctx *ctx, grn_dat_cursor *c)
を追加しました。カーソルが保持できるレコード数の最大値を
size_t
として返します。(このAPIはDATテーブル用です。)
grn_table_cursor_get_max_n_records(grn_ctx *ctx, grn_table_cursor *cursor)
を追加しました。カーソルが保持できるレコード数の最大値を返します。
全ての種類(
TABLE_NO_KEY
,TABLE_HASH_KEY
,TABLE_DAT_KEY
,TABLE_PAT_KEY
)のテーブルで使えます。
grn_result_set_add_xxx
を追加しました。詳細は以下の通りです。grn_result_set_add_record(grn_ctx *ctx, grn_hash *result_set, grn_posting *posting, grn_operator op)
結果セットのテーブルにレコードを追加します。
grn_ii_posting_add_float
は10.0.3から非推奨になりました。代わりにgrn_rset_add_records()
を使ってください。
grn_result_set_add_table(grn_ctx *ctx, grn_hash *result_set, grn_obj *table, double score, grn_operator op)
結果セットにテーブルを追加します。
grn_result_set_add_table_cursor(grn_ctx *ctx, grn_hash *result_set, grn_table_cursor *cursor, double score, grn_operator op)
結果セットにカーソル内のレコードを追加します。
grn_vector_copy(grn_ctx *ctx, grn_obj *src, grn_obj *dest)
を追加しました。vector
オブジェトをコピーします。vector
オブジェクトのコピーに成功したかどうかを返します。
grn_obj_have_source(grn_ctx *ctx, grn_obj *obj)
を追加しました。ソースカラムを持つカラムかどうかを
bool
として返します。
grn_obj_is_token_column(grn_ctx *ctx, grn_obj *obj)
を追加しました。トークンカラムかどうかを
bool
として返します。
grn_hash_add_table_cursor(grn_ctx *ctx, grn_hash *hash, grn_table_cursor *cursor, double score)
を追加しました。結果セットを一括して挿入するための関数です。
grn_ii_posting_add()
を使ってレコードを挿入するより高速です。
修正#
複数のスレッドから、同時にモジュール(トークナイザー、ノーマライザー、トークンフィルター)が使われた場合にクラッシュする問題を修正しました。
Float32
の値を表示する際の精度を修正しました。10.0.3から
Float32
の値の精度は、 8桁から7桁になります。
動的カラムのパラメーターだけが違うクエリーが実行された時にGroongaが誤ったキャッシュを使用していた問題を修正しました。 [GitHub#1102 naoaさんがパッチ提供]
感謝#
naoaさん
10.0.2リリース - 2020-04-29#
改良#
time_classify_*
関数がuvector
に対応しました。 [GitHub#1089][naoaさんがパッチ提供]uvector
とは、要素のサイズが固定のベクターです。例えば、Time型の要素を格納しているベクターは
uvector
です。
ゼロコピーで値を参照できないソートキーが混在しているケースでソートのパフォーマンスを改善しました。
いくつかのソートキー(例えば、
_score
等)の値はゼロコピーで値を参照できません。これらの値が一つでも含まれる場合、以前は全てのソートキーの値をコピーしていました。
今回の変更から、参照できないソートキーの値だけコピーし、参照可能なソートキーの値はコピーせずに参照するようにしました。
ただ、この変更で全てのソートキーの値が参照可能なケースでパフォーマンスが落ちる可能性があります。
重み付きベクターをJSON文字列としてロードできるようにしました。
以下の例のように、重み付きベクターをJSON文字列としてロードできます。
table_create Tags TABLE_PAT_KEY ShortText table_create Data TABLE_NO_KEY column_create Data tags COLUMN_VECTOR|WITH_WEIGHT Tags column_create Tags data_tags COLUMN_INDEX|WITH_WEIGHT Data tags load --table Data [ {"tags": "{\"fruit\": 10, \"apple\": 100}"}, {"tags": "{\"fruit\": 200}"} ]
Float32
型をサポートしました。Groongaは既に
Float
型を持っていますが、これは、倍精度浮動小数点数です。したがって、単精度浮動小数点数のみを使う場合は、効率が悪いです。Float32
型を追加することで、より適切な型を選択できるようになりました。
以下のAPIを公開しました。
grn_obj_unref(grn_ctx *ctx, grn_obj *obj)
このAPIは参照カウントモードのときのみ使用します。(参照カウントモードとは、
GRN_ENABLE_REFERENCE_COUNT=yes
の状態のことです。)このAPIは、参照カウントモードの時のみ
grn_obj_unlink()
を呼び出します。参照カウントモード以外の時は、何もしません。参照カウントモードの時のみ
grn_obj_unlink()
を呼び出す必要がある時に便利です。以下の例のように、参照カウントモードかどうかの条件を書かなくて良くなるためです。
grn_obj_unref()
を使用しない場合の例です。if (grn_enable_reference_count) { grn_obj_unlink(ctx, obj); }
grn_obj_ubref()
を使用する場合の例です。grn_obj_ubref(ctx, obj);
grn_get_version_major(void)
grn_get_version_minor(void)
grn_get_version_micro(void)
uint32_t
としてGroongaのメジャー、マイナー、マイクロバージョンを返します。
grn_posting_get_record_id(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_section_id(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_position(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_tf(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_weight(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_weight_float(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_rest(grn_ctx *ctx, grn_posting *posting)
これらは、ポスティングリストの情報を返します。
これらのAPIは、
grn_posting_get_weight_float
以外は、uint32_t
として値を返します。grn_posting_get_weight_float
はfloat
として値を返します。grn_posting_get_section_id(grn_ctx *ctx, grn_posting *posting)
セクションIDとはカラム名の内部表現です。
カラム名を文字列としてポスティングリストに格納すると、情報量が多くなり無駄な容量を使います。
したがって、カラム名をセクションIDという数値としてポスティングリストに格納することで、情報量を圧縮し使用する容量を少なくしています。
grn_posting_get_tf(grn_ctx *ctx, grn_posting *posting)
grn_posting_get_tf
のtf
とは、単語の出現頻度です。
grn_posting_get_weight_float(grn_ctx *ctx, grn_posting *posting)
トークンの重みを
float
として返します。今後はトークンの重みを取得する際はこのAPIを使用することをおすすめします。
近い将来、重みは内部的に
uint32_t
からfloat
に変更するためです。
修正#
32bit GUN/Linux等でGroongaがクラッシュすることがある問題を修正しました。
関係のないカラムの値をクリアーしてしまう問題を修正しました。 [GitHub#1087][sutaminさんの報告]
dump
コマンドでレコードをダンプした時にメモリリークする問題を修正しました。output_columns
に無効な値を指定した時にメモリリークする問題を修正しました。snippet
関数を実行する時にメモリリークする問題を修正しました。以下の条件を満たした時にメモリリークする問題を修正しました。
initial
ステージで動的カラムを使用した場合。select
コマンドの引数slices
を使用した場合。
logical_table_remove
でテーブルを削除した際にメモリリークする問題を修正しました。参照カウントモードを使用した時にメモリリークする問題を修正しました。
参照カウントモードとは、
GRN_ENABLE_REFERENCE_COUNT=yes
の状態のことです。この機能は実験的です。パフォーマンスが低下することがあります。
Apache Arrow形式でデータをロードした際に
_key
アクセサーを解放しすぎる問題を修正しました。
感謝#
sutaminさん
naoaさん
10.0.1リリース - 2020-03-30#
Groonga 10.0.0 のUbuntuとWindows(VC++版)のパッケージに誤りがあったため Groonga 10.0.1 をリリースしました。
既にCentOS、Debian、Windows(MinGW版)のGroonga 10.0.0を使用している方は、そのまま使っていただいて問題ありません。
修正#
Windows(VC++版)のパッケージに不足していたランタイム(vcruntime140_1.dll)を追加しました。
10.0.0リリース - 2020-03-29#
改良#
[httpd] バンドルしているnginxのバージョンを1.17.9に更新しました。
[httpd] 出力形式を拡張子として指定できるようにしました。
例えば、
load?output_type=json
の代わりにload.json
と書けます。
[ログ] Linuxのdumpレベルのログにオープンしたファイルとクローズしたファイルのパスを出力するようにしました。
[ログ] Windowsのdebugレベルのログにオープンしたファイルとクローズしたファイルのパスを出力するようにしました。
以下のAPIとマクロを追加しました。
grn_timeval_from_double(grn_ctx, double)
このAPIは、
double
型をgrn_timeval
型に変換します。grn_timeval
型の値を返します。
GRN_TIMEVAL_TO_NSEC(timeval)
このマクロは、
grn_timeval
型の値をuint64_t
型の値としてナノ秒に変換します。
GRN_TIME_USEC_TO_SEC(usec)
このマクロは、ミリ秒を秒に変換します。
以下のマクロを非推奨にしました。
GRN_OBJ_FORMAT_FIN(grn_ctx, grn_obj_format)
10.0.0から代わりに
grn_obj_format_fin(grn_ctx, grn_obj_format)
を使ってください。
[logical_range_filter],[dump] ストリーム出力に対応しました。
この機能は
command_version 3
以降で使えます。headerがbodyの後に出力されます。現在、この機能をサポートしているのは、
dump
とlogical_range_filter
のみです。logical_range_filter
は、command_version 3
以降では、常に出力がstreamとして返ります。この機能は以下の制限があります。
limit
に指定できる負の値は -1 のみです。MessagePack形式の出力はサポートしていません。
この変更で、JSONの応答内容を少し変更しています。
以下のように以前のバージョンとは、キーの順序が異なっています。
以前のバージョンのキーの順序
{ "header": {...}, "body": {...} }
本バージョン(10.0.0)のキーの順序
{ "body": {...}, "header": {...} }
dump
とlogical_range_filter
をcommand_version 3
で実行した時はキャッシュが効きません。10.0.0から
dump
とlogical_range_filter
はcommand_version 3
の時にストリームで応答を返すので、応答全体をキャッシュできないためです。
[logical_range_filter] Apache Arrow形式での応答をサポートしました。
以下のデータ型をサポートしています。
UInt8
Int8
UInt16
Int16
UInt32
Int32
UInt64
Int64
Time
ShortText
Text
LongText
Vector
ofInt32
Reference vector
Ubuntu 20.04 (Focal Fossa)をサポートしました。
Ubuntu 19.04 (Disco Dingo)のサポートをやめました。
このバージョンはEOLになっているためです。