本文へスキップ
`Ctrl`+`K`

# お知らせ - 14系

## 14.1.3リリース - 2025-01-27

### 改良

#### 静的なインデックス構築方法: 並列実行をサポート

たくさんのCPUコアがある場合、静的なインデックス構築方法を高速化できます。この機能は `column_create ... COLUMN_INDEX ... --n_workers -1` とすることで使うことができます。

多くの場合、これを使うことで静的なインデックス構築方法速度は2-10倍高速になります。

#### language_model_vectorize: Phi-4をサポート

言語モデルとしてPhi-4を使うことができます。Phi-4はエンべディング生成用に設計されていないことに注意してください。

#### NormalizerNFKCを追加

NormalizerNFKC150のような既存の`NormalizerNFKC*`としています。しかし、`NormalizerNFKC*`より汎用的です。

NormalizerNFKCは使用するUnicodeのバージョンをversion引数で指定できます。たとえば、`NormalizerNFKC("version", "15.0.0")`と`NormalizerNFKC150`は等価です。

NormalizerNFKCの導入により`NormalizerNFKC*`は非推奨となりました。新しく書くアプリケーションではNormalizerNFKCを使うべきです。

NormalizerNFKCはデフォルトでUnicode 16.0.0を使います。

#### TokenFilterNFKCを追加

TokenFilterNFKC150のような既存の`TokenFilterNFKC*`と似ています。しかし、NormalizerNFKCを使います。そのため、Unicodeのバージョンをversionで指定できます。

TokenFilterNFKCの導入により`TokenFilterNFKC*`は非推奨となりました。新しく書くアプリケーションではTokenFilterNFKCを使うべきです。

TokenFilterNFKCはデフォルトでUnicode 16.0.0を使います。

#### Amazon Linux: Amazon Linux 2023 aarch64をサポート

インストール方法はAmazon Linuxを参照してください。

#### index_column_diff: プログレスログの変更をサポート

他のデバッグログなしでプログレスログだけを見たい場合に有用です。

詳細はprogress_log_levelを参照してください。

### 修正

#### AVXがないマシン上でdeb/rpmパッケージを使えなかった問題を修正

pgroonga/pgroonga#642

Groongaは言語モデルを使うためにllama.cppを使っています。llama.cppは高速処理のためにSIMDを使っています。

SIMDがllama.cppの初期化処理を遅延するようにしました。そのため、language_model_vectorizeのように言語モデル関連の機能を使わない場合はAVXがないマシンでもGroongaを使うことができます。

しらゆきさんが報告しました。

#### TABLE_PAT_KEY: defrag後に既存のキーが壊れるかもしれない問題を修正

TABLE_PAT_KEY内にゴミノードが残った状態でdefragをすると、このTABLE_PAT_KEYに追加したキーが既存のキーを上書きしてしまうかもしれませんでした。

このバグは14.1.1リリース - 2024-12-03から存在していました。

#### TABLE_PAT_KEY: defrag時にいくつかのWALが抜けていた問題を修正

defrag中にいくつか漏れていたWALを追加しました。WALが漏れていると、defrag中にクラッシュした場合に復旧できないことがあります。

#### defrag: TABLE_PAT_KEYのカラムが処理されない問題を修正

GH-2168

`defrag pat`は`pat`とそのカラムを処理するべきです。しかし、14.1.1リリース - 2024-12-03から`pat`しか処理しなくなっていました。これはリグレッションバグです。

#### インデックスカラム: 静的なインデックス構築方法の問題を修正

次の場合に発生していました。

- ソースが参照ベクターカラム

- ソースが`1..-2`の位置に`GRN_ID_NIL`な要素（なにも参照していない要素）を持つ

- インデックスカラムに`WITH_POSITION`フラグを指定している

静的なインデックス構築では、`GRN_ID_NIL`要素の後のすべての要素で間違った位置情報を使っていました。

静的なインデックス構築では、間違ったインデックスキーを使うことがありました。これが発生するかどうかは未初期化のメモリーの内容に依存します。

#### TABLE_HASH_KEY: ゴミエントリーが再利用されないかもしれない問題を修正

ゴミエントリーがある状態でTABLE_HASH_KEYをリハッシュすると発生します。レコードを削除するとゴミエントリーが増えます。

ゴミエントリーがあるときにリハッシュされると、リハッシュ後はそのゴミエントリーが再利用されなくなります。すこしの有効なレコードしかないときでもTABLE_HASH_KEYが巨大になってしまう可能性があります。

この問題は10.1.1リリース - 2021-01-25から存在していました。

### 感謝

- しらゆきさん

## 14.1.2リリース - 2024-12-24

### 改良

#### LGPL-2.1-onlyからLGPL-2.1-or-laterにライセンスを変更

GH-1774

これでGPL 3以降と一緒に使いやすくなります。

#### delete: 参照重み付きベクターをサポート

参照されているカラムにインデックスがあると、`delete`は参照されているカラム内にある削除された参照されている値も一緒に削除します。参照ベクターカラムでもこの機能は動いていましたが、参照「重み付き」ベクターカラムでは動いていませんでした。

このリリースから参照「重み付き」ベクターカラムでも動くようになります。

### 修正

#### ベクターカラム: 必要なキャストが実行されないことがある問題を修正

Groongaは必要に応じて自動的に値をキャストします。

参照ベクターカラムが32ビット浮動小数点数の重みを使っていて、新しい値が重みなし参照ベクターの場合、Groongaは新しい値をキャストしなければいけません。しかし、キャストしていませんでした。

## 14.1.1リリース - 2024-12-03

### 改良

#### RapidJSONの同梱を終了

GH-1462

14.0.7でsimdjsonをサポートしました。これによりRapidJSONを同梱する必要がなくなりました。RapidJSONにはJSONライセンスのファイルが含まれていました。JSONライセンスはフリーソフトウェアライセンス・オープンソースライセンスではありません。そのため、RapidJSONの同梱をやめたかったのです。

RapidJSONはまだサポートしています。別途RapidJSONをインストールすることで引き続きRapidJSONを使うことができます。しかし、RapidJSONよりsimdjsonを使うことをオススメします。

#### llama.cppの初期化処理を遅延化

GH-2078

llama.cppは最近のSIMD機能を必要とします。llama.cppを常に初期化すると、古いCPUを使っていて、かつ、llama.cppの機能を使っていないユーザーが公式のGroongaパッケージを使えません。そのため、llama.cppの初期化を遅延させることにしました。llama.cpp関連の機能を使っているユーザーは引き続き最近のCPUが必要ですが、llama.cpp関連の機能を使っていないユーザーはこれまで通り古いCPUを使えます。

#### `NormalizerNFKC`: `unify_middle_dot`と`remove_symbol`を同時使用をサポート

GH-1538

NormalizerNFKC150のような`NormalizerNFKC`関連のノーマライザーでunify_middle_dotオプションとremove_symbolオプションを一緒に使えるようになりました。

#### defrag: TABLE_PAT_KEYをサポート

TABLE_PAT_KEYテーブルは削除されたキーの領域を再利用できませんでした。この領域は引き続き自動では再利用されませんが、このリリースからは明示的にdefragを実行することで再利用できるようになりました。

#### load: エラー処理を改良

load中にクリティカルなエラーが発生したときは後続のデータを待たないようにしました。このようなケースではクライアントは後続のデータを送らないかもしれません。

#### groonga 実行ファイル: `context_id`ログフラグを追加

クエリーログも使っている場合に便利です。クエリーログではコンテキストIDが記録されています。プロセスログとクエリーログの中にコンテキストIDが記録されていると、これらのログをより簡単に紐付けられるようになります。

#### groonga 実行ファイル: エラー処理を改良

リクエストタイムアウト 内部的にロックしています。場合によっては失敗することがあります。このようなケースを想定していくつかエラーチェックを追加しました。

#### TABLE_PAT_KEY: キー領域を効率化

GH-2104

キー領域を無駄使いするケースがありました。このケースを改良して、できるだけ効率よくキー領域を使えるようにしました。

### 修正

#### `grn_pat_size()`: エラー時に`0`を返さない問題を修正

GH-2097

指定された`pat`が`NULL`の場合、`-22`を返していました。しかし、エラーの場合は`0`を返して、`ctx->rc`にエラー情報を設定するべきでした。

Groongaが期待した挙動をするようになりました。

#### 正規表現: 空のパターンのときの問題を修正

GH-2121

指定されたパターンが空文字列の場合、いくつかも問題がありました。

- 正規表現用のインデックスがある場合、Groongaがクラッシュしていました。

- 正規表現用のインデックスがない場合、Groongaはすべてのレコードを返していました。

空のパターンのときは空の結果を返すようにしました。

## 14.1.0リリース - 2024-11-05

### 改良

#### [status] `.["features"]["llama.cpp"]`エントリーを追加

`.["features"]`エントリーは次のように各機能が有効かどうかを示しています。

    [
      ["..."],
      {
        "...": "...",
        "features": {
          "nfkc": true,
          "mecab": true,
          "...": "..."
        },
        "...": "..."
      }
    ]

このリリースは`.["features"]`エントリーに`llama.cpp`を追加しました。

    [
      ["..."],
      {
        "...": "...",
        "features": {
          "nfkc": true,
          "mecab": true,
          "...": "...",
          "llama.cpp": true,
          "...": "..."
        },
        "...": "..."
      }
    ]

llama.cppが有効になっているかどうかを確認するために`.["features"]["llama.cpp"]`を使うことができます。

次で紹介するlanguage_model_vectorizeを使うためにはllama.cppサポートが必要です。

#### [language_model_vectorize] 追加（実験的）

この機能はまだ実験的で安定していません。

この機能は従来よりも多くのCPUとメモリーを使うかもしれません。

この関数は、与えられたテキストの正規化されたエンべディング（ベクトル表現）を返します。エンべディングとは、与えられたテキストの意味情報をベクトルとして表現したものです。意味をベクトルとして表現することで、全文検索ではなくセマンティックサーチができるようになります。

例えば、「牛乳」と「ミルク」は字面は全然違いますが、同じ意味を持つ言葉です。従来でも同義語展開を使えば「牛乳」と「ミルク」のような字面の異なる意味が同じ言葉を検索できますが、同義語展開用のテーブルをメンテナンスしなければなりません。

セマンティックサーチができるようになると、同義語展開用のテーブルを準備、メンテナンスせずに意味の近い言葉を検索できるようになります。

#### [column_create] generator引数を追加

このリリースでは生成カラム機能を追加しました。この機能を使うと、他のカラムの値を使ってカラムの値を自動生成できます。

column_createとgeneratorを使うと生成カラムを作ることができます。詳細は自動生成カラムを作成を参照してください。

この機能のメリットは次のとおりです。

1. 生成処理を手動で管理する必要がない

2. 生成元のカラムだけあればよいので、ロードするデータ量を減らせる

たとえば、他のカラムの値のエンべディングを生成するためにlanguage_model_vectorizeを使うことができます。エンべディングは小さくないかもしれません。もし、エンべディングが1024次元の32-bit浮動小数点数で表現されている場合、エンべディングのサイズは4KiBになります。language_model_vectorizeと生成カラムでエンべディングを自動で生成すると4KiBのエンべディング一式をGroongaに送る必要はありません。

この機能により、検索対象のテキストをloadするだけで、同時に対応するエンべディングも保存できます。

### 修正

#### [GQTP] 間違ったリターンコードが返される問題を修正

これはクライアント側の問題です。この問題は14.0.0から存在します。

GQTPクライアントはサーバーから受け取ったリターンコードを間違って変換していました。たとえば、`INVALID_ARGUMENT`の値は`-22`ですが、これを`65514`に変換していました。

GQTPクライアントを利用していないユーザーには影響ありません。

#### [logical_range_filter] 不正なJSONフォーマットのレスポンスが返されることがある問題を修正

この問題はコマンドバージョン 3でのみ発生します。デフォルトのコマンドバージョンは1です。

あなたのGroongaのデフォルトのコマンドバージョンはstatusコマンドで確認できます。

    [
      ["..."],
      {
        "...": "...",
        "command_version": 1,
        "default_command_version": 1,
        "...": "..."
      }
    ]

以下が不正なJSONフォーマットのレスポンス例です。実際の`"records: [...]"`の前に不要な`"records": []`があります。

    {
      "body": {
        "columns": ["..."],
        "records": [],
        "records": [
          [
            "The first post!",
            "Welcome! This is my first post!",
            1436313600.0,
            5,
            "Hello"
          ],
          "..."
        ]
      },
      "header": "..."
    }

#### [logical_range_filter] 不正なJSONフォーマットのレスポンスが返されることがある問題を修正

request_cancelで実行中のコマンドを止めることができます。

コマンドをキャンセルすると不正なJSONフォーマットのレスポンスを受け取ることがありました。これはキャンセルのタイミングによって発生したりしなかったりします。

このリリースではキャンセル処理時の出力処理を改良しました。コマンドをキャンセルしたときでも不正なJSONフォーマットのレスポンスを受け取ることはなくなるはずです。

#### [index_column_diff] 擬陽性の差分が報告されるかもしれない問題を修正

index_column_diffを使うとインデックスの破損を検出できます。

1つのレコード中に同じトークンが131,072個以上含まれている場合、index_column_diffは本来インデックス内にあるべきレコードが含まれていないと報告します。このリリースではこの問題を修正しました。

## 14.0.9リリース - 2024-09-27

### 修正

- Alpine Linux 3.20上でソースからビルドする時にビルドエラーになる問題を修正しました。

## 14.0.8リリース - 2024-09-25

### 改良

- [Amazon Linux 2023] Amazon Linux 2023 をサポートしました。 [GH-1845][takoyaki-nyokkiさんとWatsonさんの報告]

  今の所、Amazon Linux 2023のaarch64版はサポートしていません。パッケージのビルドに時間がかかりすぎるため、メンテナンスコストが高いためです。

  Amazon Linux 2023版のGroongaではTokenMecabが使えません。Amazon Linux 2023がMecabパッケージを提供していないためです。

### 修正

- Windows版のPGroongaで`pgroonga.log_type`を指定するとクラッシュする問題を修正しました。

### 感謝

- takoyaki-nyokkiさん

- Watsonさん

## 14.0.7リリース - 2024-09-03

### 改良

- [NormalizerNFKC] 新しいオプション `unify_latin_alphabet_with` を追加しました。[pgroonga/pgroonga#418][Man Hoangさんの報告]

  このオプションは、以下のように発音記号付きの文字と発音記号なしの文字を同じ文字とみなすことができます。

  ただし、この機能は `LATIN (SMALL|CAPITAL) LETTER X WITH XXX` にのみフォーカスしています。 `LATIN (SMALL|CAPITAL) LETTER X` + `COMBINING XXX` はサポートしていません。

  以下の例で、`ngoan`で`ngoằn`を取得できることが確認できます。

      table_create --name Contents --flags TABLE_HASH_KEY --key_type ShortText
      column_create --table Contents --name content --type ShortText
      load --table Contents
      [
        {"_key":"1", "content":"con đường ngoằn nghoèo"},
      ]

      table_create \
        --name Terms \
        --flags TABLE_PAT_KEY \
        --key_type ShortText \
        --default_tokenizer TokenBigram \
        --normalizer 'NormalizerNFKC150("unify_latin_alphabet_with", true)'
      column_create \
        --table Terms \
        --name index_content \
        --flags COLUMN_INDEX|WITH_POSITION \
        --type Contents \
        --source content

      select --table Contents --query content:@ngoan
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              1
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "_key",
                "ShortText"
              ],
              [
                "content",
                "ShortText"
              ]
            ],
            [
              1,
              "1",
              "con đường ngoằn nghoèo"
            ]
          ]
        ]
      ]

  注釈

  現在のノーマライザーには、以下の問題があります。

  小文字の `U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE` は `U+0069 LATIN SMALL LETTER I` でなければなりませんが、現在の実装では、 `U+0069 LATIN SMALL LETTER I` + `U+0307 COMBINING DOT ABOVE` を使ってしまいます。

  この問題は、NormalizerNFKC160から修正する予定です。

- simdjson をサポートしました。

  現状、RapidJSONのサポートも維持しますが、RapidJSONは今後サポートをやめる予定です。

- [Ubuntu] Ubuntu 23.10 (Mantic Minotaur)のサポートをやめました。

  Ubuntu 23.10 は 2024-07-11 にEOLになったためです。

- `libedit`を有効にしたパッケージを配布するようにしました。

  Groonga REPLで↑キーを使ってコマンド履歴を参照できるようになりました。

### 修正

- [status] "h3"が`groonga --version`や`status`で表示されない問題を修正しました。

- ログローテートが有効な時にクラッシュする問題を修正しました。

  この問題は、以下の条件で発生します。

  1. 以下のオプションを指定して、ファイルにロギングする時。

     - `--log-path <path>`

     - `--query-log-path <path>`

  2. 以下のオプションを指定して、ログローテートが有効な時。

     - `--log-rotate-threshold-size <threshold>`

     - `--query-log-rotate-threshold-size <threshold>`

  3. 以下のオプションを指定して、プロセスIDの出力が有効な時。

     - `--log-flags process_id`

- `GRN_WITH_BUNDLED_ONIGMO=OFF`を指定しているにも関わらず、GroongaがバンドルされているOnigmoを使う問題を修正しました。[termux/termux-packages#21252][Biswapriyo Nathさんがパッチ提供]

### 感謝

- Man Hoangさん

- Biswapriyo Nathさん

## 14.0.6リリース - 2024-07-29

### 改良

- インデックスを設定していないベクターカラムに対して、前方一致検索ができるようになりました。

  すでに、インデックスを設定したベクターカラムに対しては前方一致検索できますが、インデックスを設定していないベクターカラムに対しては、今まで前方一致検索できませんでした。

  このリリースから、以下のようにインデックスを設定していないベクターカラムに対しても前方一致検索ができます。

      table_create Users TABLE_NO_KEY
      column_create Users name COLUMN_VECTOR ShortText

      load --table Users
      [
      {"name": ["alice"]},
      {"name": ["bob"]},
      {"name": ["callum"]},
      {"name": ["elly", "alice"]},
      {"name": ["marshal"]}
      ]

      select Users --query 'name:^al'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              2
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "name",
                "ShortText"
              ]
            ],
            [
              1,
              [
                "alice"
              ]
            ],
            [
              4,
              [
                "elly",
                "alice"
              ]
            ]
          ]
        ]
      ]

- [Debian GNU/Linux] Debian 11 (bullseye) のサポートをやめました。

## 14.0.5リリース - 2024-07-04

### 改良

- CentOS 7のサポートをやめました。

  CentOS 7はEOLになったためです。

- 可能な限りオブジェクト（テーブルやカラム）を削除する機能を追加しました。

  この機能は主にPGroongaのクラッシュセーフ機能で使います。

  PGroongaは`Custom WAL Resource Managers`を使うことで、PGroongaのWALをスタンバイへ自動で適用できるようになります。ただ、`Custom WAL Resource Managers`を使用していると、オブジェクトの破損などでPGroongaのWALの適用に失敗した場合にすべてのレプリケーションが停止します。そのため、壊れたオブジェクトがデータベース内に存在する場合、Groongaはこの機能を使って、できる限り壊れたオブジェクトを削除しようとします。

### 修正

- [query] `query()`の`AND`検索と`OR`検索検索を `'A || query("...", "B C")'` の順で組み合わせたときに、誤った順序で評価される問題を修正しました

  以下の例では、`memo @ "Groonga`の条件がマッチする`{"name": "Alice", "memo": "Groonga user"}`がヒットするはずですが、 この問題が発生した場合はヒットしません。したがって、下記の例では何もヒットしません。

      table_create Users TABLE_NO_KEY
      column_create Users name COLUMN_SCALAR ShortText
      column_create Users memo COLUMN_SCALAR ShortText

      load --table Users
      [
      {"name": "Alice", "memo": "Groonga user"},
      {"name": "Bob",   "memo": "Rroonga user"}
      ]
      select Users \
        --output_columns 'name, memo, _score' \
        --filter 'memo @ "Groonga" || query("name", "Bob Rroonga")'
      [[0,0.0,0.0],[[[0],[["name","ShortText"],["memo","ShortText"],["_score","Int32"]]]]]

  修正後は、以下のように`{"name": "Alice", "memo": "Groonga user"}`がヒットします。

      select Users \
        --output_columns 'name, memo, _score' \
        --filter 'memo @ "Groonga" || query("name", "Bob Rroonga")'
      [
        [
          0,
          1719376617.537505,
          0.002481460571289062
        ],
        [
          [
            [
              1
            ],
            [
              [
                "name",
                "ShortText"
              ],
              [
                "memo",
                "ShortText"
              ],
              [
                "_score",
                "Int32"
              ]
            ],
            [
              "Alice",
              "Groonga user",
              1
            ]
          ]
        ]
      ]

  この問題の発生条件は下記の通りです。

  - `OR`検索と`query()`を組み合わせて使っていること。

  - `query()`内で`AND`検索していること。

  - `'A || query("...", "B C")'`の順序で条件式が記述されていること。

  そのため、`query()`を単独で使用している場合や、`query()`内で`AND`検索をしていない場合は問題ありません。

- [select] `--query "A* OR B"`のように先に前方一致検索を評価する条件が、誤った検索結果を返すことがある問題を修正しました

  この問題は先に前方一致検索を評価する条件の時に発生する可能性があります。 `--query A OR B*`のように最後に前方一致検索を評価するケースでは発生しません。

  この問題が発生すると、以下の`--query "Bo* OR li"`という条件が、`Bo`も`li`も前方一致検索として評価されてしまい`li`の検索結果が誤ったものになります。 `Alice`がヒットするのが期待値ですが、以下のように何もヒットしません。これは、前述の通り`li`が前方一致検索として評価されてしまうためです。

      table_create Users TABLE_NO_KEY
      column_create Users name COLUMN_SCALAR ShortText

      load --table Users
      [
      ["name"],
      ["Alice"]
      ]

      select Users \
        --match_columns name \
        --query "Bo* OR li"
      [
        [
          0,
          1719377505.628048,
          0.0007376670837402344
        ],
        [
          [
            [
              0
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "name",
                "ShortText"
              ]
            ]
          ]
        ]
      ]

## 14.0.4リリース - 2024-05-29

### 修正

- [query_parallel_or] `query_parallel_or()`を使用すると、match_escalation_threshold または `force_match_escalation` オプションが無視される問題を修正しました。

  修正前は、検索エスカレーションを無効にしても、`query_parallel_or()`使用時はエスカレーションされていました。この問題は、`query_parallel_or()`でのみ発生します。queryでは発生しません。

  一般的には、ヒット数が0件になってしまうのは嬉しくありません。何かしらの検索結果を得たいことが多いです。したがって、通常、検索エスカレーションは無効にしません。そのため、この問題は多くのユーザーには影響がありませんが、以下のようにストップワードを利用しているユーザーには影響があります。

      plugin_register token_filters/stop_word

      table_create Memos TABLE_NO_KEY
      column_create Memos content COLUMN_SCALAR ShortText

      table_create Terms TABLE_PAT_KEY ShortText \
        --default_tokenizer TokenBigram \
        --normalizer NormalizerAuto \
        --token_filters TokenFilterStopWord
      column_create Terms memos_content COLUMN_INDEX|WITH_POSITION Memos content
      column_create Terms is_stop_word COLUMN_SCALAR Bool
      load --table Terms
      [
      {"_key": "and", "is_stop_word": true}
      ]

      load --table Memos
      [
      {"content": "Hello"},
      {"content": "Hello and Good-bye"},
      {"content": "Good-bye"}
      ]

      select Memos \
        --filter 'query_parallel_or(["content", "content", "content", "content"], \
                  "and", \
                  {"options": {"TokenFilterStopWord.enable": true}})' \
        --match_escalation_threshold -1 \
        --sort_keys -_score

  ストップワードとして登録したキーワードではマッチしてほしくありません。そのため、上記の例では、`match_escalation_threshold`に`-1`を設定しています。エスカレーションが無効でかつ、ストップワードに検索キーワード（`and`）が登録されているため、上記の例では、Groongaは何もレコードを返さないことが期待値です。しかし、この問題が発生すると、Groongaはマッチしたレコードを返却してしまいます。`query_parallel_or()`を使うと、`match_escalation_threshold`が効かないためです。

- 参照ベクターカラムに対する全文検索が動作しない問題を修正しました。

  この問題は、Groonga v14.0.0以降で発生します。また、この問題は、参照ベクターカラムに対して全文検索を実行している場合に影響があります。

  以下の例では、Groongaが`[1, "Linux MySQL"]` と `[2, "MySQL Groonga"]`を返すことが期待ですが、修正前は、以下のように常に0件ヒットになっていました。参照ベクターカラムに対して全文検索しているためです。

      table_create bugs TABLE_PAT_KEY UInt32

      table_create tags TABLE_PAT_KEY ShortText --default_tokenizer TokenDelimit
      column_create tags name COLUMN_SCALAR ShortText

      column_create bugs tags COLUMN_VECTOR tags

      load --table bugs
      [
      ["_key", "tags"],
      [1, "Linux MySQL"],
      [2, "MySQL Groonga"],
      [3, "Mroonga"]
      ]

      column_create tags bugs_tags_index COLUMN_INDEX bugs tags

      select --table bugs --filter 'tags @ "MySQL"'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              0
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "_key",
                "UInt32"
              ],
              [
                "tags",
                "tags"
              ]
            ]
          ]
        ]
      ]

## 14.0.3リリース - 2024-05-09

### 改良

- 以下の最適化を行いました。

  - ヒット数が多いときの`OR`検索と`AND`検索のパフォーマンスを向上しました。

  - 前方一致検索(`@^`)のパフォーマンスを向上しました。

  - `A AND B`という条件で、`B`より`A`のレコード数が多い場合の`AND`検索のパフォーマンスを向上しました。

  - 多くの動的カラムを設定している場合の検索パフォーマンスを向上しました。

- [TokenNgram] 新しいオプション`ignore_blank`を追加しました。

  以下のように`TokenBigramIgnoreBlank`を`TokenNgram("ignore_blank", true)`で置き換えることができます。

  `TokenBigram`を使う例です。

      tokenize TokenBigram "! ! !" NormalizerAuto
      [
        [
          0,
          1715155644.64263,
          0.001013517379760742
        ],
        [
          {
            "value": "!",
            "position": 0,
            "force_prefix": false,
            "force_prefix_search": false
          },
          {
            "value": "!",
            "position": 1,
            "force_prefix": false,
            "force_prefix_search": false
          },
          {
            "value": "!",
            "position": 2,
            "force_prefix": false,
            "force_prefix_search": false
          }
        ]
      ]

  `TokenBigramIgnoreBlank`を使う例です。

      tokenize TokenBigramIgnoreBlank "! ! !" NormalizerAuto
      [
        [
          0,
          1715155680.323451,
          0.0009913444519042969
        ],
        [
          {
            "value": "!!!",
            "position": 0,
            "force_prefix": false,
            "force_prefix_search": false
          }
        ]
      ]

  `TokenNgram("ignore_blank", true)`を使う例です。

      tokenize 'TokenNgram("ignore_blank", true)' "! ! !" NormalizerAuto
      [
        [
          0,
          1715155762.340685,
          0.001041412353515625
        ],
        [
          {
            "value": "!!!",
            "position": 0,
            "force_prefix": false,
            "force_prefix_search": false
          }
        ]
      ]

- [Ubuntu] Ubuntu 24.04 LTS (Noble Numbat) をサポートしました。

### 修正

- [request_cancel] `request_cancel`コマンドで実行中のクエリーを中断した時にGroongaがクラッシュすることがある問題を修正しました。

- `--post_filter`使用時に、`--offset`の値が`--post_filter`の結果より大きい場合に予期しないエラーになる問題を修正しました。

  `--filter` と `--offset`の組み合わせで、同様のケースになった場合はエラーは発生しません。`--filter` と `--post-filter`の挙動を合わせました。

      table_create Users TABLE_PAT_KEY ShortText
      column_create Users age COLUMN_SCALAR UInt32
      load --table Users
      [
        ["_key", "age"],
        ["Alice", 21],
        ["Bob", 22],
        ["Chris", 23],
        ["Diana", 24],
        ["Emily", 25]
      ]
      select Users \
        --filter 'age >= 22' \
        --post_filter 'age <= 24' \
        --offset 3 \
        --sort_keys -age --output_pretty yes
      [
        [
          -68,
          1715224057.317582,
          0.001833438873291016,
          "[table][sort] grn_output_range_normalize failed",
          [
            [
              "grn_table_sort",
              "/home/horimoto/Work/free-software/groonga.tag/lib/sort.c",
              1052
            ]
          ]
        ]
      ]

- 近傍フレーズ直積検索で`(...)`内のすべてのフレーズがマッチしない場合に、誤った検索結果を返す場合がある問題を修正しました。

  例えば以下の、`--query '*NPP1"(a) (2)"'`で指定している`(2)`にマッチするレコードはありません。この場合は、何もヒットしないのが正しい挙動ですが、`--query '*NPP1"(a)`相当の挙動になっていました。つまり、`(2)`にマッチするレコードが無いにも関わらず、`ax1`と`axx1`がヒットしていました。

      table_create Entries TABLE_NO_KEY
      column_create Entries content COLUMN_SCALAR Text

      table_create Terms TABLE_PAT_KEY ShortText   --default_tokenizer TokenNgram
      column_create Terms entries_content COLUMN_INDEX|WITH_POSITION Entries content
      load --table Entries
      [
      {"content": "ax1"},
      {"content": "axx1"}
      ]

      select Entries \
        --match_columns content \
        --query '*NPP1"(a) (2)"' \
        --output_columns 'content'
      [
        [
          0,
          1715224211.050228,
          0.001366376876831055
        ],
        [
          [
            [
              2
            ],
            [
              [
                "content",
                "Text"
              ]
            ],
            [
              "ax1"
            ],
            [
              "axx1"
            ]
          ]
        ]
      ]

- `TABLE_HASH_KEY`のテーブルに2^28以上のレコードが存在する時にリハッシュが発生すると、リハッシュが失敗するかテーブル内のデータが壊れる問題を修正しました。

- 以下のケースでハイライト位置がずれる問題を修正しました。

  - 以下のようにハイライト対象の文字の前に全角スペースがある場合。

    `"Groonga　<span class=\"keyword\">高</span>速！"`となることが期待値ですが、以下のように`"Groonga　<span class=\"keyword\">高速</span>！"`となっていました。

        table_create Entries TABLE_NO_KEY
        column_create Entries body COLUMN_SCALAR ShortText

        table_create Terms TABLE_PAT_KEY ShortText \
          --default_tokenizer 'TokenNgram("report_source_location", true)' \
          --normalizer 'NormalizerNFKC150("report_source_offset", true)'
        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, Terms)'
        [
          [
            0,
            1715215640.979517,
            0.001608610153198242
          ],
          [
            [
              [
                1
              ],
              [
                [
                  "highlight_html",
                  null
                ]
              ],
              [
                "Groonga　<span class=\"keyword\">高速</span>！"
              ]
            ]
          ]
        ]

  - `以下のように`TokenNgram("loose_blank", true)`を使っていて、ハイライト対象の文字が全角スペースを含んでいる場合。

    `"<span class=\"keyword\">山田 太郎</span>"`となることが期待値ですが、以下のように`"<span class=\"keyword\">山田 太</span>"`となっていました。

        table_create Entries TABLE_NO_KEY
        column_create Entries body COLUMN_SCALAR ShortText

        table_create Terms TABLE_PAT_KEY ShortText \
          --default_tokenizer 'TokenNgram("loose_blank", true, "report_source_location", true)' \
          --normalizer 'NormalizerNFKC150("report_source_offset", true)'
        column_create Terms document_index COLUMN_INDEX|WITH_POSITION Entries body

        load --table Entries
        [
        {"body": "山田 太郎"}
        ]

        select Entries --output_columns \
          --match_columns body --query '山田太郎' \
          --output_columns 'highlight_html(body, Terms)' --output_pretty yes
        [
          [
            0,
            1715220409.096246,
            0.0004854202270507812
          ],
          [
            [
              [
                1
              ],
              [
                [
                  "highlight_html",
                  null
                ]
              ],
              [
                "<span class=\"keyword\">山田 太</span>"
              ]
            ]
          ]
        ]

  - 以下のようにハイライト対象の文字の先頭に空白スペースがある場合。

    `" <span class=\"keyword\">山</span>田太郎"`となることが期待値ですが、以下のように`" <span class=\"keyword\">山</span>"`となっていました。

        table_create Entries TABLE_NO_KEY
        column_create Entries body COLUMN_SCALAR ShortText

        table_create Terms TABLE_PAT_KEY ShortText \
          --default_tokenizer 'TokenNgram("report_source_location", true)' \
          --normalizer 'NormalizerNFKC150("report_source_offset", true)'
        column_create Terms document_index COLUMN_INDEX|WITH_POSITION Entries body

        load --table Entries
        [
        {"body": " 山田太郎"}
        ]

        select Entries \
          --output_columns \
          --match_columns body \
          --query '山' \
          --output_columns 'highlight_html(body, Terms)' --output_pretty yes
        [
          [
            0,
            1715221627.002193,
            0.001977920532226562
          ],
          [
            [
              [
                1
              ],
              [
                [
                  "highlight_html",
                  null
                ]
              ],
              [
                " <span class=\"keyword\">山</span>"
              ]
            ]
          ]
        ]

  - 以下のようにハイライト対象の２番めの文字が全角スペースの場合。

    `"<span class=\"keyword\">山　田</span>太郎"`となるのが期待値ですが、以下のように`"<span class=\"keyword\">山　田太</span>郎"`となっていました。

        table_create Entries TABLE_NO_KEY
        column_create Entries body COLUMN_SCALAR ShortText

        table_create Terms TABLE_PAT_KEY ShortText \
          --default_tokenizer 'TokenNgram("report_source_location", true)' \
          --normalizer 'NormalizerNFKC150("report_source_offset", true)'
        column_create Terms document_index COLUMN_INDEX|WITH_POSITION Entries body

        load --table Entries
        [
        {"body": "山　田太郎"}
        ]

        select Entries \
          --output_columns \
          --match_columns body \
          --query '山　田' \
          --output_columns 'highlight_html(body, Terms)'
        [
          [
            0,
            1715222501.496007,
            0.0005536079406738281
          ],
          [
            [
              [
                0
              ],
              [
                [
                  "highlight_html",
                  "<span class=\"keyword\">山　田太</span>郎"
                ]
              ]
            ]
          ]
        ]

## 14.0.2リリース - 2024-03-29

### 改良

- 一時テーブルに対して、normalizers/tokenizer/token_filtersを設定したときに出力されるログのログレベルを下げました。

  例えば、この変更の対象のログは以下のようなログです。

      DDL:1234567890:set_normalizers NormalizerAuto

  PGroongaは起動時に一時テーブルに対してノーマライザーを設定するため、このログがノイズになっていました。このログのログレベルは`notice`なので、PGroonga起動時にこのログが出力されてしまうためです。

  そのため、今回のリリースからこのようなログのログレベルを`debug`にしました。これにより、デフォルトでは、PGroonga起動時にこのログが出力されないようになります。

## 14.0.1リリース - 2024-03-14

### 改良

- [load] ノーマライズによって空のキーとなったキーを`load`する時のエラーを止めました。

  `"-"` は、`NormalizerNFKC150("remove_symbol", true)` によって `""` になります。そのため、以下のケースでは"empty key"エラーが報告されます。

      table_create Values TABLE_HASH_KEY ShortText \
        --normalizers 'NormalizerNFKC150("remove_symbol", true)'
      table_create Data TABLE_NO_KEY
      column_create Data value COLUMN_SCALAR Values
      load --table Data
      [
      {"value": "-"}
      ]

  しかし、このようなデータを大量に`load`した場合、多くのエラーログが生成されます。Groongaは空の文字列をインデックスに登録できないため、"empty key"エラーを大量に出力するためです。

  ただ、このようなケースで空の文字列がインデックスへ登録できなくても問題ありません。空の文字列で検索しても何も一致しないためです。そのため、このようなケースの時に"empty key"エラーを報告するのを止めました。

### 修正

- between または、範囲検索時にリクエストキャンセルするとGroongaがクラッシュする問題を修正しました。

  この問題は必ず発生するわけではありません。特定のタイミングでリクエストキャンセルをすると発生します。シーケンシャルサーチなどの検索時間が長い場合に発生しやすいです。

- 以下の条件を満たした時に highlight_html が正しくない結果を返すことがあります。

  - `NormalizerTable` and `NormalizerNFKC150`のように複数のノーマライザーを使っている。

  - 空白を含む文字列をハイライトする。

  例えば、以下のようなケースでこの問題は発生します。

      table_create NormalizationsIndex TABLE_PAT_KEY ShortText --normalizer NormalizerAuto

      table_create Normalizations TABLE_HASH_KEY UInt64
      column_create Normalizations normalized COLUMN_SCALAR LongText
      column_create Normalizations target COLUMN_SCALAR NormalizationsIndex

      column_create NormalizationsIndex index COLUMN_INDEX Normalizations target

      table_create Lexicon TABLE_PAT_KEY ShortText \
        --normalizers 'NormalizerTable("normalized", \
                                       "Normalizations.normalized", \
                                       "target", \
                                       "target"), NormalizerNFKC150'

      table_create Names TABLE_HASH_KEY UInt64
      column_create Names name COLUMN_SCALAR Lexicon

      load --table Names
      [
      ["_key","name"],
      [1,"Sato Toshio"]
      ]

      select Names \
        --query '_key:1 OR name._key:@"Toshio"' \
        --output_columns 'highlight_html(name._key, Lexicon)

      [
        [
          0,
          1710401574.332274,
          0.001911401748657227
        ],
        [
          [
            [
              1
            ],
            [
              [
                "highlight_html",
                null
              ]
            ],
            [
              "sato <span class=\"keyword\">toshi</span>o"
            ]
          ]
        ]
      ]

- [Ubuntu] Ubuntu向けパッケージを提供できるようになりました。

  Groonga 14.0.0では、GroongaのUbuntu向けパッケージを提供していませんでした。Ubuntu向けパッケージのビルド環境の問題で、パッケージを作るのに失敗したためです。

  14.0.1でこの問題を修正したので、今回のリリースからGroongaのUbuntu向けパッケージを提供できるようになりました。

- `clang` を使ってソースからビルドした時にビルドエラーになる問題を修正しました。 [GitHub#1738][Reported by windymelt]

### 感謝

- windymeltさん

## 14.0.0リリース - 2024-02-29

メジャーバージョンアップです! メジャーバージョンアップですが、互換性は壊れていないので、データベースを再構築することなく14.0.0へアップグレードできます。

### 改良

- 新しいトークナイザー`TokenH3Index`を追加しました。（実験的）

  `TokenH3Index`は、`WGS84GetPoint` を `UInt64`(H3 index)に変換します。

- 非テキストベースのトークナイザーを使ったインデックスのオンライン構築とオフライン構築をサポートしました。（実験的）

  `TokenH3Index` は、非テキストベースのトークナイザーの一つです。

- [select] 非テキストベースのトークナイザーを使ったインデックスでの検索をサポートしました。（実験的）.

  `TokenH3Index` は、非テキストベースのトークナイザーの一つです。

- 新しい関数 `distance_cosine()`, `distance_inner_product()`, `distance_l2_norm_squared()`, `distance_l1_norm()` を追加しました。

  これらの関数と`limit N`を使うことで、ベクトル的に距離の近いレコードのみを取得することができます。

  これらの関数は、`output`ステージで距離を計算します。

  ただ、これらの関数はまだ最適化できていません。

  - `distance_cosine()`: コサイン類似度を計算します。

  - `distance_inner_product()`: 内積を計算します。

  - `distance_l2_norm_squared()`: ユークリッド距離を計算します。

  - `distance_l1_norm()`: マンハッタン距離を計算します。

- 新しい関数`number_round()`を追加しました。

- [load] `load`を並列に実行できるようになりました。

  この機能は、`load`の`input_type`が`apache-arrow`の時のみ有効です。

  この機能は、一つのカラムに対し一つのスレッドを割り当てます。対象のカラムがたくさんある時に、ロード時間の短縮が期待できます。

- [select] `--filter`内で配列リテラルをなるべく、uvectorとして使えるようにしました。

  uvectorは、要素が固定長サイズのベクターです。

  すべての要素の型が同じ場合、ベクターの変わりにuvactorを使えます。

- [status] `status`の結果に`n_workers`を追加しました。

- 動的カラムの作成を最適化しました。

- [WAL] 壊れたインデックスの再構築を並列で実行できるようになりました。

- [select] `output_type=apache-arrow`の時に、`_key`が`Int64`型のテーブルへの参照カラムを表示できるようにしました。

### 修正

- [Windows] Windows向けパッケージ内の`groonga-normalizer-mysql`のドキュメントのパスを修正しました。

  今回のリリースから、`groonga-normalizer-mysql`のドキュメントは`share/`以下に格納されます。

- [select] ビットごとの演算を行うとGroongaがクラッシュすることがある問題を修正しました。