お知らせ#

12.0.9リリース - 2022-10-28#

改良#

  • [AlmaLinux] AlmaLinux 9 向けのパッケージをサポートしました。

    12.0.8リリース - 2022-10-03 でサポートしていましたが、アナウンスしていませんでした。

  • [escalate] escalate() 関数のドキュメントを追加しました。

  • [ノーマライザー] NormalizerHTML を追加しました。(実験的)

    NormalizerHTML はHTML用のノーマライザーです。

    現在 NormalizerHTML<span></span> といったタグの削除と、&amp;&#38; といった文字参照の展開を行います。

    以下は NormalizerHTML の例です。

    normalize NormalizerHTML "<span> Groonga &amp; Mroonga &#38; Rroonga </span>"
    [[0,1666923364.883798,0.0005481243133544922],{"normalized":" Groonga & Mroonga & Rroonga ","types":[],"checks":[]}]
    

    この例では、 <span></span> は削除され、 &amp;&#38;& に展開されています。

    タグを削除するかどうかは remove_tag オプションで指定できます。(remove_tag オプションのデフォルト値は true です。)

    normalize 'NormalizerHTML("remove_tag", false)' "<span> Groonga &amp; Mroonga &#38; Rroonga </span>"
    [[0,1666924069.278549,0.0001978874206542969],{"normalized":"<span> Groonga & Mroonga & Rroonga </span>","types":[],"checks":[]}]
    

    この例では、 <span></span> は削除されていません。

    文字参照を展開するかどうかは expand_character_reference オプションで指定できます。(expand_character_reference オプションのデフォルト値は true です。)

    normalize 'NormalizerHTML("expand_character_reference", false)' "<span> Groonga &amp; Mroonga &#38; Rroonga </span>"
    [[0,1666924357.099782,0.0002346038818359375],{"normalized":" Groonga &amp; Mroonga &#38; Rroonga ","types":[],"checks":[]}]
    

    この例では、 &amp;&#38; は展開されていません。

  • [httpd] バンドルしているnginxのバージョンを1.23.2に更新しました。

    CVE-2022-41741とCVE-2022-41742のセキュリティの修正が含まれています。これらのセキュリティーの修正の詳細については、https://nginx.org/en/CHANGES を参照してください。

  • メモリーが不足した際に、同じログが大量に出力されないように変更しました。

    メモリーが不足した際に、 mmap failed!!!! というメッセージが大量にログが記載されることがありました。このメッセージを可能な限り重複してログ出力されないように改良しました。

修正#

  • [select] n_workers を指定したとき、Groongaがクラッシュしたり、誤った結果を返すことがある問題を修正しました。

    この問題は、 n_workers1 より大きい値を指定し、かつ同時に drilldowns[{LABEL}].filter を使用している場合に発生していました。

    この問題は内部的な並列処理の際に、誤った値(オブジェクト)を参照していたことが原因で発生していました。そのため、上記の条件が満たされたとき、内部的に並列処理のタイミングによって、Groongaがクラッシュしたり誤った値を返すことがありました。

12.0.8リリース - 2022-10-03#

改良#

  • escalate() 関数(実験的)の仕様を使いやすいように変更しました。

    escalate() の外部の結果セットを使用しないように変更しました。

    前回の仕様では、ユーザーはどのくらいの結果が escalate() に渡されるのか推測して最初のしきい値を決める必要があり、不便でした。

    以下は前回の escalate() の例です。

    number_column > 10 && escalate(THRESHOLD_1, CONDITION_1,
                                   ...,
                                   THRESHOLD_N, CONDITION_N)
    

    CONDITION1number_column > 10 の結果が THRESHOLD_1 以下の時に実行されます。ユーザーは THRESHOLD_1 を決めるのに number_column > 10 がどのくらいの結果を返すのか推測する必要がありました。

    今回のリリースから、ユーザーが number_column > 10 がどのくらいの結果を返すのか推測する必要がなくなり、使いやすくなりました。

    この変更により、 escalate() の構文が以下の通り変更されています。

    前回の構文

    escalate(THRESHOLD_1, CONDITION_1,THRESHOLD_2, CONDITION_2, ..., THRESHOLD_N, CONDITION_N)
    

    新しい構文

    escalate(CONDITION_1, THRESHOLD_2, CONDITION_2, ..., THRESHOLD_N, CONDITION_N)
    

    以下は構文の変更の詳細です。

    • 最初の条件のためのしきい値は不要となりました。

    • 引数の指定を必須としました。最初の条件が必須となります。

    • 最初の引数を常に実行します。

    この関数は実験的な関数です。将来的にこれらの動作は変更になる可能性があります。

  • [CMakeを使ってGroongaをビルドする方法] CMakeを使ってビルドする方法を追加しました。

  • [その他] GNU Autotoolsを使ってビルドする場合に、Apache Arrowの機能を有効化/無効化する方法について追加しました。

  • [select] drilldowns[${LABEL}].table のドキュメントを追加しました。

  • [国際化] 翻訳方法を更新しました。

修正#

  • NormalizerTable で冪等でない(繰り返し実行すると結果が変わることがある)定義をした時に、Groongaが誤った結果を返すことがある問題を修正しました。

    これは、検索する値について、値を受け取った後と、トークナイズした後の二回ノーマライズしていたことが原因です。

    Groongaはレコードを追加する時に、インデックス用のテーブルに設定したトークナイザーとノーマライザーを使って、登録するデータをトークナイズしてからノーマライズしています。検索する値についても、インデックス用のテーブルに設定したトークナイザーとノーマライザーを使って、トークナイズしてからノーマライズして、その後インデックスと照合します。両者は同じトークナイザーとノーマライザーを使うので、検索する値がインデックスに登録したデータと同じであれば、インデックスに格納されている状態と同じ状態になります。

    しかし、いままでGroongaは検索する値だけを余分にノーマライズしていました。

    NormalizerAuto といった組み込みのノーマライザーは冪等である(繰り返し実行しても結果が変わらない)ため、この問題は発生しません。一方で、 NormalizerTable はユーザー自身がノーマライザーの定義をすることができます。そのため、冪等でない(繰り返し実行すると結果が変わることがある)定義をすることができました。

    NormalizerTable に冪等でない定義が存在する場合、検索する値のみが余分にノーマライズされることで、インデックスに登録したデータと検索する値が一致しない場合がありました。

    そのような場合、ヒットするはずのデータがヒットしなかったり、ヒットしないはずのデータがヒットしたりしていました。

    以下はこの問題の例です。

    table_create ColumnNormalizations TABLE_NO_KEY
    column_create ColumnNormalizations target_column COLUMN_SCALAR ShortText
    column_create ColumnNormalizations normalized COLUMN_SCALAR ShortText
    
    load --table ColumnNormalizations
    [
    {"target_column": "a", "normalized": "b"},
    {"target_column": "b", "normalized": "c"}
    ]
    
    table_create Targets TABLE_PAT_KEY ShortText
    column_create Targets column_normalizations_target_column COLUMN_INDEX \
      ColumnNormalizations target_column
    
    table_create Memos TABLE_NO_KEY
    column_create Memos content COLUMN_SCALAR ShortText
    
    load --table Memos
    [
    {"content":"a"},
    {"content":"c"},
    ]
    
    table_create \
      Terms \
      TABLE_PAT_KEY \
      ShortText \
      --default_tokenizer 'TokenNgram' \
      --normalizers 'NormalizerTable("normalized", \
                                    "ColumnNormalizations.normalized", \
                                    "target", \
                                    "target_column")'
    
    column_create Terms memos_content COLUMN_INDEX|WITH_POSITION Memos content
    
    select Memos --query content:@a
    [[0,1664781132.892326,0.03527212142944336],[[[1],[["_id","UInt32"],["content","ShortText"]],[2,"c"]]]]
    

    select Memos --query content:@a の結果の期待値は a ですが、Groongaは c を返していました。これは、入力された aColumnNormalizations の定義にしたがって b にノーマライズされ、その後、 ノーマライズされた b を更に c にノーマライズしていたためです。結果的に、入力された ac に変換され、 Memos テーブルの {"content":"c"} にマッチしていました。

12.0.7リリース - 2022-08-29#

改良#

  • 新しい関数 escalate() を追加しました。(実験的)

    escalate() 関数は既存のマッチエスカレーション( 検索 )と似ています。この関数は、全ての条件で使えます。(既存のマッチエスカレーションは、一つの転置インデックスによる全文検索で使えます。)

    escalate() 関数は検索結果の数を制限したい時に便利です。検索結果の数の制限は、 --limit でもできますが、 --limit は全ての条件を評価した後に評価されます。escalate() 関数は結果セットが THRESHOLD より多くのレコードを持っていたら、その時点で評価を終了します。つまり、 escalate() 関数は条件の評価の数を減らせる可能性があります。

    escalate() の構文は以下の通りです。

    escalate(THRESHOLD_1, CONDITION_1,
             THRESHOLD_2, CONDITION_2,
             ...,
             THRESHOLD_N, CONDITION_N)
    

    THRESHOLD_N は、0や29のような正の数です。 CONDITION_Nnumber_column > 29 のような スクリプト構文 を使った文字列です。

    現在の結果セットのレコード数が THRESHOLD_1 以下の場合、 CONDITION_1 が実行されます。同様に、 CONDITION_1 評価後の結果セットのレコード数が THRESHOLD_2 以下の場合、 CONDITION_2 が実行されます。 CONDITION_2 評価後の結果セットのレコード数が THRESHOLD_3 より大きい場合、 escalate() は終了します。

    全ての CONDITION が実行された場合、 escalate(THRESHOLD_1, CONDITION_1, ..., THRESHOLD_N, CONDITION_N)CONDITION_1 || ... || CONDITION_N と同じです。

    escalate() 関数は、 && and &! のような論理演算子と一緒に使えます。:

    number_column > 10 && escalate(THRESHOLD_1, CONDITION_1,
                                   ...,
                                   THRESHOLD_N, CONDITION_N)
    number_column > 10 &! escalate(THRESHOLD_1, CONDITION_1,
                                   ...,
                                   THRESHOLD_N, CONDITION_N)
    

    これらは、 number_column > 10 && (CONDITION_1 || ... || CONDITION_N)number_column > 10 &! (CONDITION_1 || ... || CONDITION_N) と同じです。

    しかし、これらの挙動は使いにくいため変更される可能性があります。

  • [httpd] バンドルしているnginxのバージョンを1.23.1に更新しました。

  • [select] --n_workers オプションのドキュメントを追加しました。

修正#

  • OR検索実行中に request_cancel を実行した場合、Groongaの応答が遅くなることがある問題を修正しました。

    OR検索の結果が多い場合や多くのOR条件をもつクエリー場合に、 "request_cancel" コマンドが原因でGroongaのレスポンスが遅くなることがあります。

12.0.6リリース - 2022-08-04#

改良#

  • groonga-delta用の新しいMuninプラグインを追加しました。

    このプラグインによって、以下の項目を監視できます。

    • groonga-delta-import がローカルのストレージ上の .grn ファイルをインポートできているかどうか。

    • groonga-delta-import がMySQLの差分データをインポートできているかどうか。

    • groonga-delta-apply がインポートしたデータを適用できているかどうか。

    • 適用したデータの総サイズ。

  • [column_copy] 重み付きベクターをサポートしました。

    以下のように、重み付きベクターの値を column_copy でコピーできます。

    table_create Tags TABLE_HASH_KEY ShortText
    [[0,0.0,0.0],true]
    table_create CopyFloat32Value TABLE_HASH_KEY ShortText
    [[0,0.0,0.0],true]
    column_create CopyFloat32Value source_tags COLUMN_VECTOR|WITH_WEIGHT|WEIGHT_FLOAT32 Tags
    [[0,0.0,0.0],true]
    column_create CopyFloat32Value destination_tags COLUMN_VECTOR|WITH_WEIGHT|WEIGHT_FLOAT32 Tags
    [[0,0.0,0.0],true]
    load --table CopyFloat32Value
    [
    {
      "_key": "Groonga is fast!!!",
      "source_tags": {
        "Groonga": 2.8,
        "full text search": 1.5
      }
    }
    ]
    [[0,0.0,0.0],1]
    column_copy CopyFloat32Value source_tags CopyFloat32Value destination_tags
    [[0,0.0,0.0],true]
    select CopyFloat32Value
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "_key",
              "ShortText"
            ],
            [
              "destination_tags",
              "Tags"
            ],
            [
              "source_tags",
              "Tags"
            ]
          ],
          [
            1,
            "Groonga is fast!!!",
            {
              "Groonga": 2.8,
              "full text search": 1.5
            },
            {
              "Groonga": 2.8,
              "full text search": 1.5
            }
          ]
        ]
      ]
    ]
    
  • [Ubuntu] Ubuntu 21.10 (Impish Indri) のサポートをやめました。

    Ubuntu 21.10 は、2022年7月でEOLとなったためです。

  • [Debian GNU/Linux] Debian 10 (buster) のサポートをやめました。

    Debian 10 は、2022年8月でEOLとなるためです。

修正#

  • n_workers オプションを使ってドリルダウンを並行して実行したときにGroongaがクラッシュすることがある問題を修正しました。

  • [select] --filter に非常に長い式を指定するとシンタックスエラーになる問題を修正しました。

    今まで --filter 用のスタックサイズを100にしていたため発生していました。

12.0.5リリース - 2022-06-29#

改良#

  • [select] 検索エスカレーションによる前方一致検索のパフォーマンスを少し改善しました。

  • [select] drilldowns[LABEL]._key に重み付き参照ベクターカラムを指定できるようになりました。 [GitHub#1366][naoaさんがパッチ提供]

    今までは、ドリルダウンのキーに重み付き参照ベクターカラムを指定すると、Groongaが誤った結果を返していました。

    例えば、以下のタグ検索は、今まで誤った結果を返していました。

    table_create Tags TABLE_PAT_KEY ShortText
    
    table_create Memos TABLE_HASH_KEY ShortText
    column_create Memos tags COLUMN_VECTOR|WITH_WEIGHT Tags
    column_create Memos date COLUMN_SCALAR Time
    
    load --table Memos
    [
    {"_key": "Groonga is fast!", "tags": {"full-text-search": 100}, "date": "2014-11-16 00:00:00"},
    {"_key": "Mroonga is fast!", "tags": {"mysql": 100, "full-text-search": 80}, "date": "2014-11-16 00:00:00"},
    {"_key": "Groonga sticker!", "tags": {"full-text-search": 100, "sticker": 10}, "date": "2014-11-16 00:00:00"},
    {"_key": "Rroonga is fast!", "tags": {"full-text-search": 100, "ruby": 20}, "date": "2014-11-17 00:00:00"},
    {"_key": "Groonga is good!", "tags": {"full-text-search": 100}, "date": "2014-11-17 00:00:00"}
    ]
    
    select Memos \
      --drilldowns[tags].keys tags \
      --drilldowns[tags].output_columns _key,_nsubrecs
    [
      [
        0,
        1656480220.591901,
        0.0005342960357666016
      ],
      [
        [
          [
            5
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "_key",
              "ShortText"
            ],
            [
              "date",
              "Time"
            ],
            [
              "tags",
              "Tags"
            ]
          ],
          [
            1,
            "Groonga is fast!",
            1416063600.0,
            {"full-text-search":100}
          ],
          [
            2,
            "Mroonga is fast!",
            1416063600.0,
            {"mysql":100,"full-text-search":80}
          ],
          [
            3,
            "Groonga sticker!",
            1416063600.0,
            {"full-text-search":100,"sticker":10}
          ],
          [
            4,
            "Rroonga is fast!",
            1416150000.0,
            {"full-text-search":100,"ruby":20}
          ],
          [
            5,
            "Groonga is good!",
            1416150000.0,
            {"full-text-search":100}
          ]
        ],
        {
          "tags": [
            [
              8
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "_nsubrecs",
                "Int32"
              ]
            ],
            [
              "full-text-search",
              5
            ],
            [
              "f",
              5
            ],
            [
              "mysql",
              1
            ],
            [
              "f",
              1
            ],
            [
              "sticker",
              1
            ],
            [
              "f",
              1
            ],
            [
              "ruby",
              1
            ],
            [
              "f",
              1
            ]
          ]
        }
      ]
    

    今回のリリースから上記のクエリーは、以下のように正しい結果を返します。

    select Memos   --drilldowns[tags].keys tags   --drilldowns[tags].output_columns _key,_nsubrecs
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            5
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "_key",
              "ShortText"
            ],
            [
              "date",
              "Time"
            ],
            [
              "tags",
              "Tags"
            ]
          ],
          [
            1,
            "Groonga is fast!",
            1416063600.0,
            {
              "full-text-search": 100
            }
          ],
          [
            2,
            "Mroonga is fast!",
            1416063600.0,
            {
              "mysql": 100,
              "full-text-search": 80
            }
          ],
          [
            3,
            "Groonga sticker!",
            1416063600.0,
            {
              "full-text-search": 100,
              "sticker": 10
            }
          ],
          [
            4,
            "Rroonga is fast!",
            1416150000.0,
            {
              "full-text-search": 100,
              "ruby": 20
            }
          ],
          [
            5,
            "Groonga is good!",
            1416150000.0,
            {
              "full-text-search": 100
            }
          ]
        ],
        {
          "tags": [
            [
              4
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "_nsubrecs",
                "Int32"
              ]
            ],
            [
              "full-text-search",
              5
            ],
            [
              "mysql",
              1
            ],
            [
              "sticker",
              1
            ],
            [
              "ruby",
              1
            ]
          ]
        }
      ]
    ]
    
  • [select] queryfilterpost_filter を使っていても、ドリルダウンのキーに重み付き参照ベクターカラムを指定できるようになりました。 [GitHub#1367][naoaさんがパッチ提供]

    今までは、 queryfilterpost_filter を使っているときに、ドリルダウンのキーに重み付き参照ベクターカラムを指定するとGroongaは誤った結果、またはエラーを返していました。

    例えば、今まで以下のクエリーはエラーを返していました。

    table_create Tags TABLE_PAT_KEY ShortText
    
    table_create Memos TABLE_HASH_KEY ShortText
    column_create Memos tags COLUMN_VECTOR|WITH_WEIGHT Tags
    column_create Memos date COLUMN_SCALAR Time
    
    load --table Memos
    [
    {"_key": "Groonga is fast!", "tags": {"full-text-search": 100}, "date": "2014-11-16 00:00:00"},
    {"_key": "Mroonga is fast!", "tags": {"mysql": 100, "full-text-search": 80}, "date": "2014-11-16 00:00:00"},
    {"_key": "Groonga sticker!", "tags": {"full-text-search": 100, "sticker": 10}, "date": "2014-11-16 00:00:00"},
    {"_key": "Rroonga is fast!", "tags": {"full-text-search": 100, "ruby": 20}, "date": "2014-11-17 00:00:00"},
    {"_key": "Groonga is good!", "tags": {"full-text-search": 100}, "date": "2014-11-17 00:00:00"}
    ]
    
    select Memos \
      --filter true \
      --post_filter true \
      --drilldowns[tags].keys tags \
      --drilldowns[tags].output_columns _key,_nsubrecs
    [
      [
        -22,
        1656473820.734894,
        0.03771400451660156,
        "[hash][add][           ] key size unmatch",
        [
          [
            "grn_hash_add",
            "hash.c",
            3405
          ]
        ]
      ],
      [
        [
        ]
      ]
    ]
    

    今回のリリースから上記のクエリーは、以下のように正しい結果を返します。

    select Memos \
      --filter true \
      --post_filter true \
      --drilldowns[tags].keys tags \
      --drilldowns[tags].output_columns _key,_nsubrecs
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            5
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "_key",
              "ShortText"
            ],
            [
              "date",
              "Time"
            ],
            [
              "tags",
              "Tags"
            ]
          ],
          [
            1,
            "Groonga is fast!",
            1416063600.0,
            {
              "full-text-search": 100
            }
          ],
          [
            2,
            "Mroonga is fast!",
            1416063600.0,
            {
              "mysql": 100,
              "full-text-search": 80
            }
          ],
          [
            3,
            "Groonga sticker!",
            1416063600.0,
            {
              "full-text-search": 100,
              "sticker": 10
            }
          ],
          [
            4,
            "Rroonga is fast!",
            1416150000.0,
            {
              "full-text-search": 100,
              "ruby": 20
            }
          ],
          [
            5,
            "Groonga is good!",
            1416150000.0,
            {
              "full-text-search": 100
            }
          ]
        ],
        {
          "tags": [
            [
              4
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "_nsubrecs",
                "Int32"
              ]
            ],
            [
              "full-text-search",
              5
            ],
            [
              "mysql",
              1
            ],
            [
              "sticker",
              1
            ],
            [
              "ruby",
              1
            ]
          ]
        }
      ]
    ]
    

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • naoaさん

12.0.4リリース - 2022-06-06#

改良#

  • [Ubuntu] Ubuntu 22.04 (Jammy Jellyfish)をサポートしました。

  • groonga-benchmark の提供をやめました。

    誰も使用しておらず、メンテナンスもできないためです。

  • [status] 新しい項目 memory_map_size を追加しました。

    status コマンドを使うことで、Groongaのメモリーマップサイズの合計を取得できます。

    status
    [
      [
        0,
        1654237168.304533,
        0.0001480579376220703
      ],
      {
        (omitted)
        "memory_map_size": 70098944
      }
    ]
    

    例えば、Windowsでは、Mroogaが物理メモリーとスワップ領域を使い果たした場合、それ以上メモリーをマップすることができません。そのため、この値を監視することで、メモリーが十分でない環境でもメモリーマップサイズを適切にコントロールできます。

修正#

  • 検索実行中に request_cancel を実行した時Groongaの応答が遅くなることがある問題を修正しました。

    特に、検索対象のレコード数が多い時に、Groongaの応答がとても遅くなることがあります。

  • 文字列リストをint32のベクターにキャストできない問題を修正しました。

    例えば、以下のキャストは失敗していました。

    • ["10", "100"] -> [10, 100]

    この問題は、 load の引数として、 input_typeapache-arrow を指定したときのみ発生します。 この問題は、Groonga 12.0.2以降で発生します。

  • GroongaのMuninプラグインがAlmaLinux 8 とCentOS 7上で動作しない問題を修正しました。

12.0.3リリース - 2022-04-29#

改良#

  • [logical_count] logical_count 実行中のメモリー使用量を改善しました。

    いままで、Groongaは logical_count 実行中に確保したオブジェクト(オブジェクトとは、テーブルやカラム、インデックスなどです。)と一時テーブルを logical_count の実行完了まで保持し続けていました。

    この機能によって、Groongaは、1つのシャードを処理した後すぐに参照を減らします。そのため、Groongaは、 logical_count の実行中にメモリーを解放できるようになり、Groongaのメモリー使用量を削減できることがあります。

    この機能は参照カウントモードのときのみ有効です。GRN_ENABLE_REFERENCE_COUNT=yes と設定することで、参照カウントモードを有効にできます。

    加えて、Groongaは、この機能によって logical_count 実行中に一時テーブルを動的に解放します。そのため、Groongaのメモリー使用量を削減できます。この改善は、参照カウントモードが有効でなくても効果があります。

  • [dump] MISSING_IGNORE/MISSING_NIL をサポートしました。

    MISSING_IGNORE/MISSING_NIL を持つカラムがある場合、これらのカラムのダンプに失敗していました。このリリースから、 dump コマンドはこれらのカラムをサポートしました。

  • [snippet],[snippet_html] 入力としてベクターをサポートしました。[groonga-dev,04956][Reported by shinonon]

    例えば、以下のようにJSONデータ内のベクターに対して検索キーワードの周辺テキストを抽出できます。

    table_create Entries TABLE_NO_KEY
    column_create Entries title COLUMN_SCALAR ShortText
    column_create Entries contents COLUMN_VECTOR ShortText
    
    table_create Tokens TABLE_PAT_KEY ShortText   --default_tokenizer TokenNgram   --normalizer NormalizerNFKC130
    column_create Tokens entries_title COLUMN_INDEX|WITH_POSITION Entries title
    column_create Tokens entries_contents COLUMN_INDEX|WITH_SECTION|WITH_POSITION   Entries contents
    
    load --table Entries
    [
    {
      "title": "Groonga and MySQL",
      "contents": [
        "Groonga is a full text search engine",
        "MySQL is a RDBMS",
        "Mroonga is a MySQL storage engine based on Groonga"
      ]
    }
    ]
    
    select Entries\
      --output_columns 'snippet_html(contents), contents'\
      --match_columns 'title'\
      --query Groonga
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "snippet_html",
              null
            ],
            [
              "contents",
              "ShortText"
            ]
          ],
          [
            [
              "<span class=\"keyword\">Groonga</span> is a full text search engine",
              "Mroonga is a MySQL storage engine based on <span class=\"keyword\">Groonga</span>"
            ],
            [
              "Groonga is a full text search engine",
              "MySQL is a RDBMS",
              "Mroonga is a MySQL storage engine based on Groonga"
            ]
          ]
        ]
      ]
    ]
    

    今までも、 --output_columns 'snippet_html(contents[1])' のように snippet* を指定することで以下のようにベクターに対して検索キーワードの周辺テキストを抽出できますが、この方法ではどの要素を出力すればよいかわかりません。どの要素が検索にヒットしたかわからないためです。

    select Entries\
      --output_columns 'snippet_html(contents[0]), contents'\
      --match_columns 'title'\
      --query Groonga
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "snippet_html",
              null
            ],
            [
              "contents",
              "ShortText"
            ]
          ],
          [
            [
              "<span class=\"keyword\">Groonga</span> is a full text search engine"
            ],
            [
              "Groonga is a full text search engine",
              "MySQL is a RDBMS",
              "Mroonga is a MySQL storage engine based on Groonga"
            ]
          ]
        ]
      ]
    ]
    
  • [vector_join] 新しい関数 vector_join() を追加しました。 [groonga-dev,04956][shinononさんの報告]

    この関数は各要素を結合します。この関数の第二引数で区切り文字を指定できます。

    例えば、以下のようにベクターに対して snippet()snippet_html() を実行できます。

    plugin_register functions/vector
    
    table_create Entries TABLE_NO_KEY
    column_create Entries title COLUMN_SCALAR ShortText
    column_create Entries contents COLUMN_VECTOR ShortText
    
    table_create Tokens TABLE_PAT_KEY ShortText   --default_tokenizer TokenNgram   --normalizer NormalizerNFKC130
    column_create Tokens entries_title COLUMN_INDEX|WITH_POSITION Entries title
    column_create Tokens entries_contents COLUMN_INDEX|WITH_SECTION|WITH_POSITION   Entries contents
    
    load --table Entries
    [
    {
      "title": "Groonga and MySQL",
      "contents": [
        "Groonga is a full text search engine",
        "MySQL is a RDBMS",
        "Mroonga is a MySQL storage engine based on Groonga"
      ]
    }
    ]
    
    select Entries\
      --output_columns 'snippet_html(vector_join(contents, "\n")), contents'\
      --match_columns 'title'\
      --query Groonga --output_pretty yes
    [
      [
        0,
        1650849001.524027,
        0.0003361701965332031
      ],
      [
        [
          [
            1
          ],
          [
            [
              "snippet_html",
              null
            ],
            [
              "contents",
              "ShortText"
            ]
          ],
          [
            [
              "<span class=\"keyword\">Groonga</span> is a full text search engine\nMySQL is a RDBMS\nMroonga is a MySQL storage engine based on <span class=\"keyword\">Groonga</span>"
            ],
            [
              "Groonga is a full text search engine","MySQL is a RDBMS","Mroonga is a MySQL storage engine based on Groonga"
            ]
          ]
        ]
      ]
    ]
    
  • [インデックス構築] 動的インデックス構築のようにとても大きなトークンを無視するようにしました。 [GitHub:pgroonga/pgroonga#209][Zhanzhao (Deo) Liangさんの報告]

    Groongaはエラーを発生しなくなり、静的インデックス構築を実行する時に大きなトークンを無視し警告を出力します。

修正#

  • パトリシアトライのテーブルにキーを追加できなくなることがある問題を修正しました。

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

    • パトリシアトライのテーブルにすでにキーがある場合。

    • 4096バイトのキーを追加する場合。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • shinononさん

  • Zhanzhao (Deo) Liangさん

12.0.2リリース - 2022-03-29#

改良#

  • [logical_range_filter] シャードを処理した直後に参照を減らすようにしました。

    今までGroongaは、 logical_range_filter 終了時にすべてのシャードの参照を減らしていました。この機能によって、Groongaは、シャードを処理した後すぐに参照を減らします。この機能によって、 logical_range_filter 実行中のメモリー使用量を削減できることがあります。

    この機能は参照カウントモードのときのみ有効です。GRN_ENABLE_REFERENCE_COUNT=yes と設定することで、参照カウントモードを有効にできます。

    通常、Groongaは一度でも開いたオブジェクト(テーブル、カラム、インデックスなど)をメモリ上に保持し続けますが、たくさんのオブジェクトを開いた場合、Groongaはたくさんのメモリーを使用します。参照カウントモードでは、どこからも参照されてないオブジェクトをメモリーから開放します。これにより、Groongaのメモリー使用量が減ることがあります。

  • クラッシュリカバリー機能の安定性が向上しました。

    この機能は実験的で、デフォルトで無効です。したがって、以下の改良は。一般的なユーザーには影響ありません。

    • Groongaがクラッシュしたときにインデックスが破損する問題を修正しました。

    • ロックが残留する問題を修正しました。

    • クラッシュリカバリー中にGroongaがクラッシュする問題を修正しました。

  • 無名マッピングが利用可能な時のmmapのパフォーマンスを向上しました。[GitHub:MariaDB/server#1999][David CARLIERさんの提案]

    この改善によって、Groongaのパフォーマンスが少し向上します。

  • [インデックス構築] 以下のタイプのカラムで静的インデックス構築をサポートしました。

    • 非参照重み付きベクターカラム

    • 参照重み付きベクターカラム

    • 参照スカラーカラム

    これらのカラムは、いままで、静的インデックス構築をサポートしていませんでした。そのため、これらのカラムにデータをロードしたあとに、インデックスを構築しても、インデックスの構築時間が長くなっていました。この改良によって、このケースでインデックス構築時間が短くなります。

  • [column_create] 新しいフラグ MISSING_*INVALID_* を追加しました。

    column_create に以下の新しいフラグを追加しました。

    • MISSING_ADD

    • MISSING_IGNORE

    • MISSING_NIL

    • INVALID_ERROR

    • INVALID_WARN

    • INVALID_IGNORE

    通常、データカラムが参照データカラムで存在しないキーを指定された場合、自動的に存在しないキーを作成し、新しいレコードを作ります。

    このGroongaが参照先のカラムにキーを自動的に追加する挙動は、タグ検索のような検索で便利です。Groongaがロード時に自動的にデータを追加してくれるためです。

    しかしながら、この挙動は、キー以外の値が必要な場合に不便です。キーしか存在しないレコードがあるためです。

    このリリースで追加したフラグを使ってこの挙動を変更できます。

    • MISSING_ADD: デフォルト値です。現在と同じ挙動になります。

      データカラムが参照データカラムで、存在しないキーを指定された場合、自動的にキーを作成し、新しいレコードを追加します。

    • MISSING_IGNORE:

      データカラムが参照データカラムで、存在しないキーを指定された場合、存在しないキーを無視します。参照データカラムがスカラーカラムの場合、値は GRN_ID_NIL になります。参照データカラムがベクターカラムの場合、以下のようにその要素のみを無視します。

      ["existent1", "nonexistent", "existent2"] ->
      ["existent1" "existent2"]
      
    • MISSING_NIL:

      データカラムが参照データカラムで、存在しないキーを指定された場合、スカラーカラムとベクターカラムは存在しないキーを``GRN_ID_NIL`` として扱います。

      ["existent1", "nonexistent", "existent2"] ->
      ["existent1", "" (GRN_ID_NIL), "existent2"]
      
    • INVALID_ERROR: デフォルト値です。 ベクターカラムのエラー応答を除いて、現在と同じ挙動になります。

      無効な値を設定した場合(e.g.: XXX for UInt8 scalar column)、設定操作をエラーとして扱います。データカラムがスカラーカラムの場合、 load は応答とログにエラーを報告します。データカラムがベクターカラムの場合、 load はログにエラーを報告しますが、応答にエラーを報告しません。これは非互換の変更です。

    • INVALID_WARN:

      無効な値を設定した場合(e.g.: XXX for UInt8 scalar column)、警告メッセージをログに記録し、設定操作を無視します。対象のデータカラムが参照ベクターカラムの場合、MISSING_IGNOREMISSING_NIL を使って挙動を決定します。

    • INVALID_IGNORE:

      無効な値を設定した場合(e.g.: XXX for UInt8 scalar column)、設定操作を無視します。対象のデータカラムが参照ベクターカラムの場合、MISSING_IGNOREMISSING_NIL を使って挙動を決定します。

  • [dump][column_list] MISSING_*INVALID_* フラグをサポートしました。

    これらのコマンドは、後方互換性を維持するため、 MISSING_ADDINVALID_ERROR フラグを表示しません。これらのフラグはデフォルトの挙動を表すためです。

  • [schema] MISSING_*INVALID_* フラグをサポートしました。

    後方互換性を維持するため、 MISSING_ANDINVALID_ERROR フラグを flag に表示しませんがそれぞれのカラムに、新しく missinginvalid キーが追加されます。

  • Amazon Linux 2向けのパッケージを提供するようにしました。

  • [Windows] Visual Studio 2017 でのビルドをやめました。

    GitHub Actionsで windows-2016 のイメージが使えなくなったためです。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • David CARLIERさん

12.0.1リリース - 2022-02-28#

改良#

  • [query_expand] 同義語グループをサポートしました。

    同義語検索をする場合、今までは、以下のようにキーワードとその同義語をそれぞれ定義していました。

    table_create Thesaurus TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    column_create Thesaurus synonym COLUMN_VECTOR ShortText
    # [[0, 1337566253.89858, 0.000355720520019531], true]
    load --table Thesaurus
    [
    {"_key": "mroonga", "synonym": ["mroonga", "tritonn", "groonga mysql"]},
    {"_key": "groonga", "synonym": ["groonga", "senna"]}
    ]
    

    上記のケースでは、mroonga を検索した場合、 Groongaは、意図通り、 mroonga OR tritonn OR "groonga mysql" を検索しますが、``tritonn を検索した場合は、 Groongaは、 tritonn のみを検索します。tritonn を検索した場合でも、tritonn OR mroonga OR "groonga mysql" と検索した場合、以下のように定義を追加する必要がありました。

    load --table Thesaurus
    [
    {"_key": "tritonn", "synonym": ["tritonn", "mroonga", "groonga mysql"]},
    ]
    

    多くのケースでは、 mroongamroonga OR tritonn OR "groonga mysql" と展開した場合、 tritonn"groonga mysql"mroonga OR tritonn OR "groonga mysql" と展開して欲しくなりますが、今までは、そのようなケースでは定義を追加する必要がありました。したがって、対象のキーワードに同義語がたくさんあると、同じような定義をたくさん定義する必要があるため、同義語の定義が煩雑でした。

    加えて、同義語を削除する際も、多くのレコードを削除する必要があるので面倒でした。

    今回のリリースから同義語の代表値を決めることで一つのグループを作れるようになりました。例えば、以下のすべてのキーワードは、 "mroonga" グループです。

    load --table Synonyms
    [
      {"_key": "mroonga": "representative": "mroonga"}
    ]
    
    load --table Synonyms
    [
      {"_key": "tritonn": "representative": "mroonga"},
      {"_key": "groonga mysql": "representative": "mroonga"}
    ]
    

    このケースでは、 mroongamroonga OR tritonn OR "groonga mysql" と展開されます。また、 tritonn"groonga mysql"mroonga OR tritonn OR "groonga mysql" と展開されます。

    同義語を削除する際も、対象のレコードを削除するだけです。例えば、同義語から "groonga mysql" を削除する場合は、 {"_key": "groonga mysql": "representative": "mroonga"} を削除するだけです。

  • [query_expand] 同義語グループにベクターを使えるようにしました。

    以下のように、同義語グループにベクターを使えます。

    table_create SynonymGroups TABLE_NO_KEY
    [[0,0.0,0.0],true]
    column_create SynonymGroups synonyms COLUMN_VECTOR ShortText
    [[0,0.0,0.0],true]
    table_create Synonyms TABLE_PAT_KEY ShortText
    [[0,0.0,0.0],true]
    column_create Synonyms group COLUMN_INDEX SynonymGroups synonyms
    [[0,0.0,0.0],true]
    load --table SynonymGroups
    [
    ["synonyms"],
    [["rroonga", "Ruby groonga"]],
    [["groonga", "rroonga", "mroonga"]]
    ]
    [[0,0.0,0.0],2]
    query_expand Synonyms.group "rroonga"
    [
      [
        0,
        0.0,
        0.0
      ],
      "((rroonga) OR (Ruby groonga) OR (groonga) OR (rroonga) OR (mroonga))"
    ]
    
  • 環境変数によって、バックトレースを無効にできるようにしました。

    GRN_BACK_TRACE_ENABLE を使うことで、バックトレースの出力を無効にできます。GRN_BACK_TRACE_ENABLE=no と設定すると、Groongaはバックトレースを出力しません。

    Groongaはバックトレースをスタック領域に保持します。したがって、OSによっては、Groongaがスタック領域を使い切ってしまいクラッシュする可能性があります。GRN_BACK_TRACE_ENABLE=no を使うことで、このようなケースを避けることができます。

  • [select] --slices のパフォーマンスを改善しました。

  • [Windows] VisualStudio 2022 をサポートしました。

  • [select] 近傍検索でそれぞれの要素ごとの距離を指定できるようになりました。

    例えば、近傍フレーズ検索なら、フレーズごとに最大距離を指定できます。この機能は今後ドキュメント化されます。そのため、機能の詳細は後日、共有します。

  • [Groonga HTTPサーバー] RPMパッケージのGroongaであっても、 groonga-server-http を使えるようにしました。

修正#

  • [Windows] Groongaがバックトレースを出力時にクラッシュする問題を修正しました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

12.0.0リリース - 2022-02-09#

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

まずはじめに Groonga 11.0.0 から 11.1.3 までの変更点を紹介します。次に、12.0.0の主な変更点を紹介します。

Groonga 11.0.0 から 11.1.3 までの主な変更点#

新規機能と改良#

  • [snippet] 32個以上のキーワードを使えるようにしました。

    いままで、 snippet は32個以上のキーワードを指定できませんでしたが、この改良によって、32個以上のキーワードを指定できます。

    通常の使用では、 snippet に32以上のキーワードは指定しませんが、 query_expand などを使うことによって自動的にキーワードが増加したときに対象のキーワードが32以上になることがあります。

    今までは、このようなケースでは、Groongaはエラーになっていましたが、この改良によって、エラーが発生しなくなります。

    詳細は、 release 11.1.3 を参照してください。

  • [NormalizerNFKC130] 新しいオプション remove_symbol を追加しました。

    このオプションは、正規化対象の文字列から記号(例えば #, !, ", &, % 等)を削除します。例えば、歌のタイトルやアーティスト名、お店の名前等の表記ゆれの防止に使えます。

    詳細は、 release 11.1.3 を参照してください。

  • [load] ISO 8601 形式をサポートしました。

    ISO 8601形式は一般的なフォーマットです。より一般的な形式をサポートしたことによって load の使い勝手が良くなりました。

    詳細は、 release 11.1.0 を参照してください。

  • [snippet] 正規表現を使ってスニペットの区切り文字を見つける新しいオプション delimiter_regexp を追加しました。

    この機能は検索結果を文で表示したい時に便利です。

    snippet は、検索キーワードの周辺のテキストを抽出します。 snippet で抽出したテキストをスニペットと呼びます。

    通常、 snippet は、検索キーワードの周辺の200byteのテキストを返しますが、 snippet は、センテンスの区切りを考慮しません。スニペットは、複数のセンテンスで構成されることがあります。

    delimiter_regexp オプションは、検索キーワードと同じセンテンスのテキストのみを抽出したいときに便利です。例えば、 \.\s* を使って対象のセンテンス内のテキストのみを抽出できます。文字列は、 \ でエスケープする必要があることに注意してください。

    詳細は、 release 11.0.9 を参照してください。

  • [cache_limit] cache_limit 0 を実行したときにクエリーキャッシュを削除するようにしました。

    Groongaは内部的なテーブルにクエリーキャッシュを保存しています。このテーブルは、ハッシュテーブルなので、トータルのキーサイズは最大で4GiBです。そのため、もし多くの巨大なクエリーを実行した場合、トータルのキーサイズの最大値4GiBを超え、Groongaがクエリーをキャッシュできない可能性があります。このようなケースで、 cache_limit 0 を実行することで、クエリーキャッシュ用のテーブルをクリアーし、Groongaがクエリーキャッシュを保存できるようにします。

    今まではこの問題を解消するには、Groongaを再起動する必要がありましたが、この改良によって、 cache_limit 0 を実行するだけで問題を解消できます。

    詳細は、 release 11.0.6 を参照してください。

  • [between] between() で、条件式の評価順序の最適化をサポートしました。

    GRN_EXPR_OPTIMIZE=yes を設定することで、 between() で条件式の評価順序の最適化を使えます。この最適化は、 between() で十分にレコードを絞り込めるか、 between() でほとんどレコードを絞り込めない時に効果があります。

  • [ログ] 標準出力、標準エラー出力への出力をサポートしました。

    この機能はDocker上でGroongaを実行する際に有用です。Dockerは標準で標準出力と標準エラー出力を記録する機能を持っています。したがって、Groongaのログを取得するために、Dockerの環境にログインする必要がなくなります。

    詳細は、 release 11.0.4 を参照してください。

  • [query] クエリー毎に TokenFilterStemTokenFilterStopWord を無効にできるようになりました。

    特定のクエリーでのみ TokenFilterStemTokenFilterStopWord を無効にして検索できるようになりました。

    この機能は、検索キーワードと正確に同じ語を検索したい時に便利です。通常、ステミングやストップワードの除去を有効にしたほうが良い結果を得られますが、検索キーワードと正確に同じ語を検索したい場合は、これらの機能は不要です。

    今までは、検索キーワードと正確に同じ語を検索したい場合は、専用のインデックスを作る必要がありましたが、この改良によって、専用のインデックスを作らずに検索キーワードと正確に同じ語を検索できます。

    詳細は、 release 11.0.3 を参照してください。

  • [string_slice] 新しい関数 string_slice を追加しました。

    string_slice() は、検索結果の文字列から文字の位置や正規表現を使って、部分文字列を抽出します。この機能は、検索結果を編集したい時に便利です。

    例えば、この機能は、検索結果からタグを除去するのに使えます。

  • [query_parallel_or] クエリーを並行して実行できる新しい関数を追加しました。

    query_parallel_or は query と似ていますが、 query_parallel_or は複数の OR 条件を並列に処理します。この機能を使うことで、大量のOR条件の実行速度を向上できます。

    ただ、 query_parallel_or だけで複数のCPUを使います。したがって、 query_parallel_or と同時に実行しているクエリーは速度が低下する可能性があります。

  • [トークンフィルター] オプションをつけた複数のトークンフィルターを使えるようにしました。

    以下の例のように、オプション付きのトークンフィルターを複数使うことができます。

    --token_filters 'TokenFilterStopWord("column", "ignore"), TokenFilterNFKC130("unify_kana", true)'
    
  • [select] --post_filter--slices[].post_filter をサポートしました。

    --post_filter--slices[].post_filter を使うことで、 --filter 実行後に再度フィルタリングすることができます。--post_filter--slices[].post_filter の違いは応答フォーマットです。

    --post_filter の応答フォーマットは、 --filter と同じです。--slices[].post_filter の応答フォーマットは --slices[].post_filter の実行前後の結果を出力します。

    --slices[].post_filter の応答フォーマットは、通常の select の応答と異なることに注意してください。

修正#

  • Groongaが依存している arrow-libs がバージョンアップしたことによって、Groongaのバージョンアップが失敗する問題を修正しました。

    ただし、 arrow-libs がメジャーバージョンアップした場合は、この問題は再発します。その場合は、Groongaパッケージを再構築して対応する予定です。

    This bug only occurs AlmaLinux 8 and CentOS 7.

  • [Windows] メモリー不足によって、新しくファイルのオープンに失敗した時にリソースリークする問題を修正しました。

  • オプションをサポートしているトークナイザーやノーマライザー、トークンフィルターが使われている際、多くの検索クエリーを送信するとGroongaが応答を返さなくなることがある問題を修正しました。

  • インデックス内のデータを大量に追加、削除、更新した際にインデックスが破損することがある問題を修正しました。

    この問題は、インデックス内のデータを大量に削除しただけでも発生します。ただ、インデックスにデータを追加しただけでは発生しません。

    詳細は、 release 11.0.0 を参照してください。

新しくサポートしたOS#

  • [AlmaLinux] AlmaLinux 8 向けのパッケージをサポートしました。

  • [AlmaLinux] ARM64版 AlmaLinux 8 向けのパッケージをサポートしました。

  • [Debian GNU/Linux] Debian 11 (Bullseye) をサポートしました。

  • [Debian GNU/Linux] ARM64版 Debian 11 (Bullseye) と ARM64版 Debian 10 (buster) をサポートしました。

  • [Ubuntu] Ubuntu 21.10 (Impish Indri)をサポートしました。

サポートをやめたOS#

  • [CentOS] CentOS 8のサポートをやめました。

  • [Ubuntu] Ubuntu 21.04 (Hirsute Hippo)のサポートをやめました。

  • [Ubuntu] Ubuntu 20.10 (Groovy Gorilla)のサポートをやめました。

  • [Ubuntu] Ubuntu 16.04 LTS (Xenial Xerus)のサポートをやめました。

  • [Windows] Linux上のMinGWを使ってクロスコンパイルしていた以下のWindows向けパッケージの提供をやめました。

    • groonga-x.x.x-x86.exe

    • groonga-x.x.x-x86.zip

    • groonga-x.x.x-x64.exe

    • groonga-x.x.x-x86.zip

感謝#

  • naoaさん

  • Anthony M. Cookさん

  • MASUDA Kazuhiroさん

  • potiさん

  • Takashi Hashidaさん

  • higchiさん

  • wi24rdさん

  • Josep Sanzさん

  • Keitaro YOSHIMURAさん

  • shibanao4870さん

12.0.0 の主な変更点は以下の通りです。

改良#

  • [sub_filter] 新しいオプション pre_filter_threshold を追加しました。

    このオプションで、 GRN_SUB_FILTER_PRE_FILTER_THRESHOLD の値を変更できます。Groongaが sub_filter 実行時に レコード数が GRN_SUB_FILTER_PRE_FILTER_THRESHOLD 以下だった場合、Groongaは既に絞り込んだレコードに対して sub_filter を実行します。

    -1にすると、常にこの最適化を有効にできます。

  • [index_column_have_source_record] 新しい関数 index_column_have_source_record() を追加しました。

    インデックスに存在するトークンがGroongaに登録されているいずれかのレコードに含まれているかどうかを確認できます。

    Groongaは、レコードの更新によってどのレコードからも使われていないトークンがあっても、それを削除しません。したがって、例えば、オートコンプリート機能を使っていると、検索候補としてどのレコードにも含まれていないトークンを返す可能性がありますが、この関数をつかうことで、不要なトークンを返さないようにできます。

    この関数は、トークンがどのレコードにも含まれていないことを検出できるからです。

  • [NormalizerNFKC130] 新しいオプション strip を追加しました。

    このオプションは、先頭と末尾から空白を削除します。

    normalize \
    'NormalizerNFKC121("strip", true, \
                       "report_source_offset", true)' \
    "  hello world\t! \t " \
    WITH_CHECKS|WITH_TYPES
     [
       [
         0,
         0.0,
         0.0
       ],
       {
         "normalized": "hello world!",
         "types": [
           "alpha",
           "alpha",
           "alpha",
           "alpha",
           "alpha",
           "others",
           "alpha",
           "alpha",
           "alpha",
           "alpha",
           "alpha|blank",
           "symbol|blank"
         ],
         "checks": [
           3,
           1,
           1,
           1,
           1,
           1,
           1,
           1,
           1,
           1,
           1,
           2
         ],
         "offsets": [
           0,
           3,
           4,
           5,
           6,
           7,
           8,
           9,
           10,
           11,
           12,
           14
         ]
       }
     ]
    
  • [select] 新しい引数 drilldown_max_n_target_recordsdrilldown[${LABEL}].max_n_target_records を追加しました。

    ドリルダウン対象のテーブル(フィルター結果)の中のうち最大で何レコードをドリルダウンに使うかを指定します。もし、フィルター結果のレコード数が指定した値より大きかったらフィルターした結果内のいくつかのレコードはドリルダウンには使われません。これらの引数のデフォルト値は、 -1 です。これらの引数に -1 がセットされた場合、Groongaは全てのレコードをドリルダウンに使います。

    この機能はフィルター結果が非常に大きくなるかもしれない場合に有用です。大きなフィルター結果に対するドリルダウンは遅くなることがあるためです。この機能を使うことでドリルダウンに使うレコード数を制限できます。

    以下はドリルダウンに使う最大レコード数を制限する例です。最後の2レコード( {"_id": 4, "tag": "Senna"}{"_id": 5, "tag": "Senna"} )は使われていません。

    table_create Entries TABLE_HASH_KEY ShortText
    column_create Entries content COLUMN_SCALAR Text
    column_create Entries n_likes COLUMN_SCALAR UInt32
    column_create Entries tag COLUMN_SCALAR ShortText
    
    table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
    column_create Terms entries_key_index COLUMN_INDEX|WITH_POSITION Entries _key
    column_create Terms entries_content_index COLUMN_INDEX|WITH_POSITION Entries content
    load --table Entries
    [
    {"_key":    "The first post!",
     "content": "Welcome! This is my first post!",
     "n_likes": 5,
     "tag": "Hello"},
    {"_key":    "Groonga",
     "content": "I started to use Groonga. It's very fast!",
     "n_likes": 10,
     "tag": "Groonga"},
    {"_key":    "Mroonga",
     "content": "I also started to use Mroonga. It's also very fast! Really fast!",
     "n_likes": 15,
     "tag": "Groonga"},
    {"_key":    "Good-bye Senna",
     "content": "I migrated all Senna system!",
     "n_likes": 3,
     "tag": "Senna"},
    {"_key":    "Good-bye Tritonn",
     "content": "I also migrated all Tritonn system!",
     "n_likes": 3,
     "tag": "Senna"}
    ]
    
    select Entries \
      --limit -1 \
      --output_columns _id,tag \
      --drilldown tag \
      --drilldown_max_n_target_records 3
    [
      [
        0,
        1337566253.89858,
        0.000355720520019531
      ],
      [
        [
          [
            5
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "tag",
              "ShortText"
            ]
          ],
          [
            1,
            "Hello"
          ],
          [
            2,
            "Groonga"
          ],
          [
            3,
            "Groonga"
          ],
          [
            4,
            "Senna"
          ],
          [
            5,
            "Senna"
          ]
        ],
        [
          [
            2
          ],
          [
            [
              "_key",
              "ShortText"
            ],
            [
              "_nsubrecs",
              "Int32"
            ]
          ],
          [
            "Hello",
            1
          ],
          [
            "Groonga",
            2
          ]
        ]
      ]
    ]
    
  • [httpd] バンドルしているnginxのバージョンを1.21.6に更新しました。

11.1.3リリース - 2022-01-29#

改良#

  • [snippet] 32個以上のキーワードを使えるようにしました。 [GitHub#1313][Takashi Hashidaさんがパッチ提供]

    いままで、 snippet は32個以上のキーワードを指定できませんでしたが、この改良によって、以下のように32個以上のキーワードを指定できます。

    table_create Entries TABLE_NO_KEY
    column_create Entries content COLUMN_SCALAR ShortText
    
    load --table Entries
    [
    {"content": "Groonga is a fast and accurate full text search engine based on inverted index. One of the characteristics of Groonga is that a newly registered document instantly appears in search results. Also, Groonga allows updates without read locks. These characteristics result in superior performance on real-time applications.\nGroonga is also a column-oriented database management system (DBMS). Compared with well-known row-oriented systems, such as MySQL and PostgreSQL, column-oriented systems are more suited for aggregate queries. Due to this advantage, Groonga can cover weakness of row-oriented systems.\nThe basic functions of Groonga are provided in a C library. Also, libraries for using Groonga in other languages, such as Ruby, are provided by related projects. In addition, groonga-based storage engines are provided for MySQL and PostgreSQL. These libraries and storage engines allow any application to use Groonga. See usage examples."},
    {"content": "In widely used DBMSs, updates are immediately processed, for example, a newly registered record appears in the result of the next query. In contrast, some full text search engines do not support instant updates, because it is difficult to dynamically update inverted indexes, the underlying data structure.\nGroonga also uses inverted indexes but supports instant updates. In addition, Groonga allows you to search documents even when updating the document collection. Due to these superior characteristics, Groonga is very flexible as a full text search engine. Also, Groonga always shows good performance because it divides a large task, inverted index merging, into smaller tasks."}
    ]
    
    select Entries \
      --output_columns ' \
      snippet(content, \
      "groonga", "inverted", "index", "fast", "full", "text", "search", "engine", "registered", "document", \
      "results", "appears", "also", "system", "libraries", "for", "mysql", "postgresql", "column-oriented", "dbms", \
      "basic", "ruby", "projects", "storage", "allow", "application", "usage", "sql", "well-known", "real-time", \
      "weakness", "merging", "performance", "superior", "large", "dynamically", "difficult", "query", "examples", "divides", \
      { \
        "default_open_tag": "[", \
        "default_close_tag": "]", \
        "width" : 2048 \
      })'
    [
      [
        0,
        1643165838.691991,
        0.0003311634063720703
      ],
      [
        [
          [
            2
          ],
          [
            [
              "snippet",
              null
            ]
          ],
          [
            [
              "[Groonga] is a [fast] and accurate [full] [text] [search] [engine] based on [inverted] [index]. One of the characteristics of [Groonga] is that a newly [registered] [document] instantly [appears] in [search] [results]. [Also], [Groonga] [allow]s updates without read locks. These characteristics result in [superior] [performance] on [real-time] [application]s.\n[Groonga] is [also] a [column-oriented] database management [system] ([DBMS]). Compared with [well-known] row-oriented [system]s, such as [MySQL] and [PostgreSQL], [column-oriented] [system]s are more suited [for] aggregate queries. Due to this advantage, [Groonga] can cover [weakness] of row-oriented [system]s.\nThe [basic] functions of [Groonga] are provided in a C library. [Also], [libraries] [for] using [Groonga] in other languages, such as [Ruby], are provided by related [projects]. In addition, [groonga]-based [storage] [engine]s are provided [for] [MySQL] and [PostgreSQL]. These [libraries] and [storage] [engine]s [allow] any [application] to use [Groonga]. See [usage] [examples]."
            ]
          ],
          [
            [
              "In widely used [DBMS]s, updates are immediately processed, [for] example, a newly [registered] record [appears] in the result of the next [query]. In contrast, some [full] [text] [search] [engine]s do not support instant updates, because it is [difficult] to [dynamically] update [inverted] [index]es, the underlying data structure.\n[Groonga] [also] uses [inverted] [index]es but supports instant updates. In addition, [Groonga] [allow]s you to [search] [document]s even when updating the [document] collection. Due to these [superior] characteristics, [Groonga] is very flexible as a [full] [text] [search] [engine]. [Also], [Groonga] always shows good [performance] because it [divides] a [large] task, [inverted] [index] [merging], into smaller tasks."
            ]
          ]
        ]
      ]
    ]
    
  • [NormalizerNFKC130] 新しいオプション remove_symbol を追加しました。

    このオプションは、以下のように正規化対象の文字列から記号(例えば #, !, ", &, % 等)を削除します。

    normalize   'NormalizerNFKC130("remove_symbol", true)'   "#This & is %% a pen."   WITH_TYPES
    [
      [
        0,
        1643595008.729597,
        0.0005540847778320312
      ],
      {
        "normalized": "this  is  a pen",
        "types": [
          "alpha",
          "alpha",
          "alpha",
          "alpha",
          "others",
          "others",
          "alpha",
          "alpha",
          "others",
          "others",
          "alpha",
          "others",
          "alpha",
          "alpha",
          "alpha"
        ],
        "checks": [
        ]
      }
    ]
    
  • [AlmaLinux] ARM64版 AlmaLinux 8 向けのパッケージをサポートしました。

  • [httpd] バンドルしているnginxのバージョンを1.21.5に更新しました。

  • [Documentation] ruby_eval の誤記を修正しました。[GitHub#1317][wi24rdさんがパッチ提供]

  • [Ubuntu] Ubuntu 21.04 (Hirsute Hippo)サポートをやめました。

    • Ubuntu 21.04 は、2022年1月20日でEOLとなったためです。

修正#

  • [load] 存在しないカラムを指定してロードした時にクラッシュする問題を修正しました。

    この問題は、 load の引数として、 input_typeapache-arrow を指定したときのみ発生します。

  • Groongaが依存している arrow-libs がバージョンアップしたことによって、Groongaのバージョンアップが失敗する問題を修正しました。[groonga-talk,540][Josep Sanzさんの報告][Gitter,61eaaa306d9ba23328d23ce1][shibanao4870さんの報告][GitHub#1316][Keitaro YOSHIMURAさんの報告]

    ただし、 arrow-libs がメジャーバージョンアップした場合は、この問題は再発します。その場合は、Groongaパッケージを再構築して対応する予定です。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • Takashi Hashidaさん

  • wi24rdさん

  • Josep Sanzさん

  • Keitaro YOSHIMURAさん

  • shibanao4870さん

11.1.1リリース - 2021-12-29#

改良#

  • [select] 組み合わせフレーズ近傍検索をサポートしました。

    この機能は、 '*NP"..." OR *NP"..." OR ...' の短縮形です。例えば、以下のように、 query を使って *NP を複数実行する式のかわりに *NPP を使えます。

    query ("title * 10 || content",
           "*NP"a 1 x" OR
            *NP"a 1 y" OR
            *NP"a 1 z" OR
            *NP"a 2 x" OR
            *NP"a 2 y" OR
            *NP"a 2 z" OR
            *NP"a 3 x" OR
            *NP"a 3 y" OR
            *NP"a 3 z" OR
            *NP"b 1 x" OR
            *NP"b 1 y" OR
            *NP"b 1 z" OR
            *NP"b 2 x" OR
            *NP"b 2 y" OR
            *NP"b 2 z" OR
            *NP"b 3 x" OR
            *NP"b 3 y" OR
            *NP"b 3 z"")
    

    この機能によって、上記の式を *NPP"(a b) (1 2 3) (x y z)" と書くことができます。加えて、 *NPP"(a b) (1 2 3) (x y z)" は、 '*NP"..." OR *NP"..." OR ...' より高速です。

    query ("title * 10 || content",
           "*NPP"(a b) (1 2 3) (x y z)"")
    

    この機能は、 '*NP"..." OR *NP"..." OR ...' のような近傍フレーズ検索のパフォーマンスを改善するために実装されました。

  • [select] 順序付き組み合わせフレーズ近傍検索をサポートしました。

    この機能は、 '*ONP"..." OR *ONP"..." OR ...' の短縮形です。例えば、以下のように、 query を使って *ONP を複数実行する式のかわりに *ONPP を使えます。

    query ("title * 10 || content",
           "*ONP"a 1 x" OR
            *ONP"a 1 y" OR
            *ONP"a 1 z" OR
            *ONP"a 2 x" OR
            *ONP"a 2 y" OR
            *ONP"a 2 z" OR
            *ONP"a 3 x" OR
            *ONP"a 3 y" OR
            *ONP"a 3 z" OR
            *ONP"b 1 x" OR
            *ONP"b 1 y" OR
            *ONP"b 1 z" OR
            *ONP"b 2 x" OR
            *ONP"b 2 y" OR
            *ONP"b 2 z" OR
            *ONP"b 3 x" OR
            *ONP"b 3 y" OR
            *ONP"b 3 z"")
    

    この機能によって、上記の式を *ONPP"(a b) (1 2 3) (x y z)" と書くことができます。加えて、 *ONPP"(a b) (1 2 3) (x y z)" は、 '*ONP"..." OR *ONP"..." OR ...' より高速です。

    query ("title * 10 || content",
           "*ONPP"(a b) (1 2 3) (x y z)"")
    

    この機能は '*ONP"..." OR *ONP"..." OR ...' のような順序付き近傍フレーズ検索のパフォーマンスを改善するために実装されました。

  • [request_cancel] 検索実行中に request_cancel を検知しやすくしました。

    request_cancel を検知するために、リターンコードのチェックを増やしたためです。

  • [thread_dump] 新しいコマンド thread_dump を追加しました。

    現状、このコマンドはWindowsでしか動作しません。

    このコマンド実行時の全てのスレッドのバックトレースをNOTICEレベルのログとして出力できます。

    この機能は、Groongaが応答を返さない等の問題を解決するのに役立ちます。

  • [CentOS] CentOS 8のサポートをやめました。

    CentOS 8は、2021年12月31日でEOLとなるためです。

修正#

  • 無効なパラメータを持つインデックスカラムを削除できない問題を修正しました。 [GitHub#1301][Takashi Hashidaさんがパッチ提供]

    • 例えば、以下のように column_create を使って無効なインデックスカラムを作成した時、テーブルが削除できなくなります。

      table_create Statuses TABLE_NO_KEY
      column_create Statuses start_time COLUMN_SCALAR UInt16
      column_create Statuses end_time COLUMN_SCALAR UInt16
      
      table_create Times TABLE_PAT_KEY UInt16
      column_create Times statuses COLUMN_INDEX Statuses start_time,end_time
      [
        [
          -22,
          1639037503.16114,
          0.003981828689575195,
          "grn_obj_set_info(): GRN_INFO_SOURCE: multi column index must be created with WITH_SECTION flag: <Times.statuses>",
          [
            [
              "grn_obj_set_info_source_validate",
              "../../groonga/lib/db.c",
              9605
            ],
            [
              "/tmp/d.grn",
              6,
              "column_create Times statuses COLUMN_INDEX Statuses start_time,end_time"
            ]
          ]
        ],
        false
      ]
      table_remove Times
      [
        [
          -22,
          1639037503.16515,
          0.0005414485931396484,
          "[object][remove] column is broken: <Times.statuses>",
          [
            [
              "remove_columns",
              "../../groonga/lib/db.c",
              10649
            ],
            [
              "/tmp/d.grn",
              8,
              "table_remove Times"
            ]
          ]
        ],
        false
      ]
      

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • Takashi Hashidaさん

11.1.0リリース - 2021-11-29#

改良#

  • [load] ISO 8601 形式をサポートしました。[GitHub#1228][Takashi Hashidaさんがパッチ提供]

    この変更によって、load は、以下のフォーマットをサポートします。

    • YYYY-MM-ddThh:mm:ss.sZ

    • YYYY-MM-ddThh:mm:ss.s+10:00

    • YYYY-MM-ddThh:mm:ss.s-10:00

    この構文の TZ の代わりに tz を使うこともできます。- の代わりに / を使うこともできます。ただし、 / は、ISO 8601 形式ではないことに注意してください。/ は互換性のためにサポートしています。

    plugin_register functions/time
    
    table_create Logs TABLE_NO_KEY
    column_create Logs case COLUMN_SCALAR ShortText
    column_create Logs created_at COLUMN_SCALAR Time
    column_create Logs created_at_text COLUMN_SCALAR ShortText
    
    load --table Logs
    [
    {"case": "timezone: Z", "created_at": "2000-01-01T10:00:00Z", "created_at_text": "2000-01-01T10:00:00Z"},
    {"case": "timezone: z", "created_at": "2000-01-01t10:00:00z", "created_at_text": "2000-01-01T10:00:00z"},
    {"case": "timezone: 00:00", "created_at": "2000-01-01T10:00:00+00:00", "created_at_text": "2000-01-01T10:00:00+00:00"},
    {"case": "timezone: +01:01", "created_at": "2000-01-01T11:01:00+01:01", "created_at_text": "2000-01-01T11:01:00+01:01"},
    {"case": "timezone: +11:11", "created_at": "2000-01-01T21:11:00+11:11", "created_at_text": "2000-01-01T21:11:00+11:11"},
    {"case": "timezone: -01:01", "created_at": "2000-01-01T08:59:00-01:01", "created_at_text": "2000-01-01T08:59:00-01:01"},
    {"case": "timezone: -11:11", "created_at": "1999-12-31T22:49:00-11:11", "created_at_text": "1999-12-31T22:49:00-11:11"},
    {"case": "timezone hour threshold: +23:00", "created_at": "2000-01-02T09:00:00+23:00", "created_at_text": "2000-01-02T09:00:00+23:00"},
    {"case": "timezone minute threshold: +00:59", "created_at": "2000-01-01T10:59:00+00:59", "created_at_text": "2000-01-01T10:59:00+00:59"},
    {"case": "timezone omitting minute: +01", "created_at": "2000-01-01T11:00:00+01", "created_at_text": "2000-01-01T11:00:00+01"},
    {"case": "timezone omitting minute: -01", "created_at": "2000-01-01T09:00:00-01", "created_at_text": "2000-01-01T09:00:00-01"},
    {"case": "timezone: localtime", "created_at": "2000-01-01T19:00:00", "created_at_text": "2000-01-01T19:00:00"},
    {"case": "compatible: date delimiter: /", "created_at": "2000/01/01T10:00:00Z", "created_at_text": "2000/01/01T10:00:00Z"},
    {"case": "decimal", "created_at": "2000-01-01T11:01:00.123+01:01", "created_at_text": "2000-01-01T11:01:00.123+01:01"}
    ]
    
    select Logs \
      --limit -1 \
      --output_columns "case, time_format_iso8601(created_at), created_at_text"
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            14
          ],
          [
            [
              "case",
              "ShortText"
            ],
            [
              "time_format_iso8601",
              null
            ],
            [
              "created_at_text",
              "ShortText"
            ]
          ],
          [
            "timezone: Z",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T10:00:00Z"
          ],
          [
            "timezone: z",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T10:00:00z"
          ],
          [
            "timezone: 00:00",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T10:00:00+00:00"
          ],
          [
            "timezone: +01:01",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T11:01:00+01:01"
          ],
          [
            "timezone: +11:11",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T21:11:00+11:11"
          ],
          [
            "timezone: -01:01",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T08:59:00-01:01"
          ],
          [
            "timezone: -11:11",
            "2000-01-01T19:00:00.000000+09:00",
            "1999-12-31T22:49:00-11:11"
          ],
          [
            "timezone hour threshold: +23:00",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-02T09:00:00+23:00"
          ],
          [
            "timezone minute threshold: +00:59",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T10:59:00+00:59"
          ],
          [
            "timezone omitting minute: +01",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T11:00:00+01"
          ],
          [
            "timezone omitting minute: -01",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T09:00:00-01"
          ],
          [
            "timezone: localtime",
            "2000-01-01T19:00:00.000000+09:00",
            "2000-01-01T19:00:00"
          ],
          [
            "compatible: date delimiter: /",
            "2000-01-01T19:00:00.000000+09:00",
            "2000/01/01T10:00:00Z"
          ],
          [
            "decimal",
            "2000-01-01T19:00:00.123000+09:00",
            "2000-01-01T11:01:00.123+01:01"
          ]
        ]
      ]
    ]
    
  • [select] 新しい query_flags DISABLE_PREFIX_SEARCH を追加しました。

    以下のように、DISABLE_PREFIX_SEARCH によって、前方一致検索の演算子の ^* を検索キーワードとして使えます。

    この機能は、 ^* を含むドキュメントを検索したい時に便利です。

    table_create Users TABLE_PAT_KEY ShortText
    
    load --table Users
    [
    {"_key": "alice"},
    {"_key": "alan"},
    {"_key": "ba*"}
    ]
    
    select Users \
      --match_columns "_key" \
      --query "a*" \
      --query_flags "DISABLE_PREFIX_SEARCH"
    [[0,0.0,0.0],[[[1],[["_id","UInt32"],["_key","ShortText"]],[3,"ba*"]]]]
    
    table_create Users TABLE_PAT_KEY ShortText
    
    load --table Users
    [
    {"_key": "alice"},
    {"_key": "alan"},
    {"_key": "^a"}
    ]
    
    select Users \
      --query "_key:^a" \
      --query_flags "ALLOW_COLUMN|DISABLE_PREFIX_SEARCH"
    [[0,0.0,0.0],[[[1],[["_id","UInt32"],["_key","ShortText"]],[3,"^a"]]]]
    
  • [select] 新しい query_flags DISABLE_AND_NOT を追加しました。

    以下のように、 DISABLE_AND_NOT によって、 AND NOT の演算子の - を検索キーワードとして使えます。

    この機能は、 - を含むドキュメントを検索したい時に便利です。

    table_create Users TABLE_PAT_KEY ShortText
    
    load --table Users
    [
    {"_key": "alice"},
    {"_key": "bob"},
    {"_key": "cab-"}
    ]
    
    select Users   --match_columns "_key"   --query "b - a"   --query_flags "DISABLE_AND_NOT"
    [[0,0.0,0.0],[[[1],[["_id","UInt32"],["_key","ShortText"]],[3,"cab-"]]]]
    

修正#

  • [ブラウザーベースの管理ツール] レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信される問題を修正しました。 [Github#1186][Takashi Hashidaさんがパッチ提供]

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • Takashi Hashidaさん

11.0.9リリース - 2021-11-04#

改良#

  • [snippet] 正規表現を使ってスニペットの区切り文字を見つける新しいオプション delimiter_regexp を追加しました。

    snippet は、検索キーワードの周辺のテキストを抽出します。 snippet で抽出したテキストをスニペットと呼びます。

    通常、 snippet は、検索キーワードの周辺の200byteのテキストを返しますが、 snippet は、センテンスの区切りを考慮しません。スニペットは、複数のセンテンスで構成されることがあります。

    delimiter_regexp オプションは、検索キーワードと同じセンテンスのテキストのみを抽出したいときに便利です。例えば、以下のように、 \.\s* を使って対象のセンテンス内のテキストのみを抽出できます。文字列は、 \ でエスケープする必要があることに注意してください。

    table_create Documents TABLE_NO_KEY
    column_create Documents content COLUMN_SCALAR Text
    
    table_create Terms TABLE_PAT_KEY ShortText --default_tokenizer TokenBigram  --normalizer NormalizerAuto
    column_create Terms documents_content_index COLUMN_INDEX|WITH_POSITION Documents content
    
    load --table Documents
    [
    ["content"],
    ["Groonga is a fast and accurate full text search engine based on inverted index. One of the characteristics of groonga is that a newly registered document instantly appears in search results. Also, groonga allows updates without read locks. These characteristics result in superior performance on real-time applications."],
    ["Groonga is also a column-oriented database management system (DBMS). Compared with well-known row-oriented systems, such as MySQL and PostgreSQL, column-oriented systems are more suited for aggregate queries. Due to this advantage, groonga can cover weakness of row-oriented systems."]
    ]
    
    select Documents \
      --output_columns 'snippet(content, \
                                { \
                                   "default_open_tag": "[", \
                                   "default_close_tag": "]", \
                                   "delimiter_regexp": "\\\\.\\\\s*" \
                                })' \
      --match_columns content \
      --query "fast performance"
    [
      [
        0,
        1337566253.89858,
        0.000355720520019531
      ],
      [
        [
          [
            1
          ],
          [
            [
              "snippet",
              null
            ]
          ],
          [
            [
              "Groonga is a [fast] and accurate full text search engine based on inverted index",
              "These characteristics result in superior [performance] on real-time applications"
            ]
          ]
        ]
      ]
    ]
    
  • [window_rank] 新しい関数 window_rank() を追加しました。

    • ギャップを含む各レコードの順位を計算できます。通常、順位は、複数のレコードが同じ順位の時は増加しません。例えば、ソートキーの値が 100、 100、 200の場合、これらの順位は 1、 1、 3です。1位のレコードが2つあるので、最後のレコードの順位は2ではなく3です。

      これは、 window_record_number と似ていますが、 window_record_number はギャップを考慮しません。

      table_create Points TABLE_NO_KEY
      column_create Points game COLUMN_SCALAR ShortText
      column_create Points score COLUMN_SCALAR UInt32
      
      load --table Points
      [
      ["game",  "score"],
      ["game1", 100],
      ["game1", 200],
      ["game1", 100],
      ["game1", 400],
      ["game2", 150],
      ["game2", 200],
      ["game2", 200],
      ["game2", 200]
      ]
      
      select Points \
        --columns[rank].stage filtered \
        --columns[rank].value 'window_rank()' \
        --columns[rank].type UInt32 \
        --columns[rank].window.sort_keys score \
        --output_columns 'game, score, rank' \
        --sort_keys score
      [
        [
          0,
          1337566253.89858,
          0.000355720520019531
        ],
        [
          [
            [
              8
            ],
            [
              [
                "game",
                "ShortText"
              ],
              [
                "score",
                "UInt32"
              ],
              [
                "rank",
                "UInt32"
              ]
            ],
            [
              "game1",
              100,
              1
            ],
            [
              "game1",
              100,
              1
            ],
            [
              "game2",
              150,
              3
            ],
            [
              "game2",
              200,
              4
            ],
            [
              "game2",
              200,
              4
            ],
            [
              "game1",
              200,
              4
            ],
            [
              "game2",
              200,
              4
            ],
            [
              "game1",
              400,
              8
            ]
          ]
        ]
      ]
      
  • [in_values] テーブル検索時に自動的にキャストするようにしました。

    例えば、 キーの型が UInt64 のテーブルに UInt32 の値をロードした場合、Groongaは、 in_values() でテーブルを検索するときに自動的に値を UInt64 にキャストします。ただ、 in_values(_key, 10) はこの機能の対象外です。10は、 Int32 として解釈されるためです。

    table_create Numbers TABLE_HASH_KEY UInt64
    load --table Numbers
    [
    {"_key": 100},
    {"_key": 200},
    {"_key": 300}
    ]
    
    select Numbers   --output_columns _key   --filter 'in_values(_key, 200, 100)'   --sortby _id
    [[0,0.0,0.0],[[[2],[["_key","UInt64"]],[100],[200]]]]
    
  • [httpd] バンドルしているnginxのバージョンを1.21.3に更新しました。

  • [AlmaLinux] AlmaLinux 8 向けのパッケージをサポートしました。

  • [Ubuntu] Ubuntu 21.10 (Impish Indri)をサポートしました。

修正#

  • Groongaがコマンドエラー(例えば、filterのシンタックスエラー)発生時に応答を返さない問題を修正しました。

    • これは、 --output_type apache-arrow を使っているときのみ発生します。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

11.0.7リリース - 2021-09-29#

改良#

  • [load] "[int, int,...]" のような文字列を [int, int,...] のような整数のベクターにキャストするようにしました。

    例えば、以下のように、"[1, -2]" のようなベクターを文字列としてロードしたとしても、 [1, -2] のように整数のベクターとして扱います。

    table_create Data TABLE_NO_KEY
    column_create Data numbers COLUMN_VECTOR Int16
    table_create Numbers TABLE_PAT_KEY Int16
    column_create Numbers data_numbers COLUMN_INDEX Data numbers
    
    load --table Data
    [
    {"numbers": "[1, -2]"},
    {"numbers": "[-3, 4]"}
    ]
    
    dump   --dump_plugins no   --dump_schema no
    load --table Data
    [
    ["_id","numbers"],
    [1,[1,-2]],
    [2,[-3,4]]
    ]
    
    column_create Numbers data_numbers COLUMN_INDEX Data numbers
    select Data --filter 'numbers @ -2'
    [[0,0.0,0.0],[[[1],[["_id","UInt32"],["numbers","Int16"]],[1,[1,-2]]]]]
    

    この機能は以下の型をサポートします。

    • Int8

    • UInt8

    • Int16

    • UInt16

    • Int32

    • UInt32

    • Int64

    • UInt64

  • [load] 文字列として表現されたJSON配列を文字列のベクターとしてロードできるようにしました。

    例えば、以下のように "["hello", "world"]" のような文字列として表現されたJSON配列をロードした場合、 ["hello", "world"] のように2つの要素を持つベクターとして扱います。

    table_create Data TABLE_NO_KEY
    [[0,0.0,0.0],true]
    column_create Data strings COLUMN_VECTOR ShortText
    [[0,0.0,0.0],true]
    table_create Terms TABLE_PAT_KEY ShortText   --normalizer NormalizerNFKC130   --default_tokenizer TokenNgram
    [[0,0.0,0.0],true]
    column_create Terms data_strings COLUMN_INDEX Data strings
    [[0,0.0,0.0],true]
    load --table Data
    [
    {"strings": "[\"Hello\", \"World\"]"},
    {"strings": "[\"Good-bye\", \"World\"]"}
    ]
    [[0,0.0,0.0],2]
    dump   --dump_plugins no   --dump_schema no
    load --table Data
    [
    ["_id","strings"],
    [1,["Hello","World"]],
    [2,["Good-bye","World"]]
    ]
    
    column_create Terms data_strings COLUMN_INDEX Data strings
    select Data --filter 'strings @ "bye"'
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "strings",
              "ShortText"
            ]
          ],
          [
            2,
            [
              "Good-bye",
              "World"
            ]
          ]
        ]
      ]
    ]
    

    以前のバージョンでは、 "["hello", "world"]" のような文字列として表現されたJSON配列をロードした場合は、 ["["hello", "world"]"] のような一つの要素を持つベクターとして扱っていました。

  • [Documentation] 以下の項目についてのドキュメントを追加しました。

    • [column_create] WEIGHT_FLOAT32 フラグについてのドキュメントを追加しました。

    • [NormalizerNFKC121] NormalizerNFKC121 についてのドキュメントを追加しました。

    • [NormalizerNFKC130] NormalizerNFKC130 についてのドキュメントを追加しました。

    • [NormalizerTable] NormalizerTable についてのドキュメントを追加しました。

  • Groongaが要求する Apache Arrow のバージョンを 3.0.0 に更新しました。[GitHub#1265][Takashi Hashidaさんがパッチ提供]

修正#

  • テーブル作成時に無効なオプションを持つトークナイザーを指定するとメモリーリークする問題を修正しました。

  • Hashテーブルに新しいエントリーを追加できなくなることがある問題を修正しました。

    このバグは、Groonga 11.0.6 でのみ発生し、頻繁にデータを追加、削除すると発生することがあります。もし、このバグが発生した場合は、以下の手順を実行することで、この問題を解決できます。

    1. Groongaを11.0.6から11.0.7以降にアップグレードします。

    2. 元のテーブルと同じスキーマを持つ新しいテーブルを作ります。

    3. 元のテーブルから新しいテーブルにデータをコピーします。

  • [Windows] メモリー不足によって、新しくファイルのオープンに失敗した時にリソースリークする問題を修正しました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • Takashi Hashidaさん

11.0.6リリース - 2021-08-29#

警告

Groonga 11.0.6 には、Hashテーブルに新しいエントリーを追加できなくなることがある問題があります。

この問題は、Groonga 11.0.7で修正しました。この問題は、Groonga 11.0.6でのみ発生します。したがって、Groonga 11.0.6をお使いの方は、Groonga 11.0.7以降を使うことを強くおすすめします。

改良#

  • クラッシュ時に自動でリカバリーする機能を追加しました。(実験的な機能です。)

    この機能は実験的な機能です。現状、この機能はまだ安定していません。

    この機能によって、Groongaがクラッシュした時、Groongaはクラッシュした後、最初のデータベースオープン時に自動的にデータベースをリカバリーします。ただ、全てのクラッシュケースで自動的にデータベースをリカバリーできるわけではありません。クラッシュのタイミングによっては、手動でデータベースのリカバリーが必要になります。

    この機能が有効な時、GroongaはWAL(ログ先行書き込み)を実行します。以下のツールを使うことでWALをダンプできますが、現状これらをユーザーが使う必要はありません。

    • [grndb] dump-wal コマンド

    • dump-wal.rb スクリプト

  • [cache_limit] cache_limit 0 を実行したときにキャッシュを削除するようにしました。[GitHub#1224][higchiさんからの報告]

    Groongaは内部的なテーブルにクエリーキャッシュを保存しています。このテーブルは、ハッシュテーブルなので、トータルのキーサイズは最大で4GiBです。そのため、もし多くの巨大なクエリーを実行した場合、トータルのキーサイズの最大値4GiBを超え、Groongaがクエリーをキャッシュできない可能性があります。このようなケースで、 cache_limit 0 を実行することで、クエリーキャッシュ用のテーブルをクリアーし、Groongaがクエリーキャッシュを保存できるようにします。

修正#

  • 同時期に複数のスレッドで同じオブジェクトをオープンした時に、Groongaがロックを解除しない問題を修正しました。

    同時期に複数のスレッドが同じオブジェクトをオープンすると、最初にオブジェクトを開いたスレッド以外のスレッドは対象のオブジェクトが開かれるまで待ちます。この時、対象のオブジェクトが開かれるのを待っているスレッドもロックを取得しますが、これらのロックは解放されません。したがって、Groongaのプロセスを再起動するまでこれらのロックが残り、その新しいスレッドは、Groongaが再起動するまで、そのオブジェクトを開けません。

    ただ、スレッドがオブジェクトを開く時間は非常に短いため、このバグは滅多に起こりません。

  • [query_parallel_or] query() と結果が異なることがある問題を修正しました。

    例えば、 query("tags || tags2", "beginner man") とした場合は、以下のレコードはマッチしますが、query_parallel_or("tags || tags2", "beginner man") とした場合は、今までは、以下のレコードはマッチしませんでした。

    • {"_key": "Bob",   "comment": "Hey!",       "tags": ["expert", "man"], "tags2": ["beginner"]}

    今回の変更によって、 query_parallel_or("tags || tags2", "beginner man") を使った場合であっても、上記のレコードがマッチするようになりました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • GRN_II_CURSOR_SET_MIN_ENABLE が原因でマッチするはずのレコードを返さないことがあります。

感謝#

  • higchiさん

11.0.5リリース - 2021-07-29#

改良#

  • [ノーマライザー] ノーマライザーを複数指定できるようになりました。

    テーブル作成時に --normalizers オプションを使うことで、複数のノーマライザーを指定できます。互換性のため、既存の --normalizer を使っても複数のノーマライザーを指定できます。

    Groonga 11.0.4 でノーマライザーをカスタマイズするための NormalizerTable を追加しました。この NormalizerTable と既存のノーマライザーを組み合わせることでより柔軟な制御ができます。

    例えば、この機能は、以下のようなケースで有用です。

    • 電話番号を検索します。ただし、データはOCRで手書きのデータを取り込みます。OCRは数字と文字列をご認識することがあります。(例えば、 5とS など)

    具体的には以下の通りです。

    table_create Normalizations TABLE_PAT_KEY ShortText
    column_create Normalizations normalized COLUMN_SCALAR ShortText
    load --table Normalizations
    [
    {"_key": "s", "normalized": "5"}
    ]
    
    
    table_create Tels TABLE_NO_KEY
    column_create Tels tel COLUMN_SCALAR ShortText
    
    table_create TelsIndex TABLE_PAT_KEY ShortText \
      --normalizers 'NormalizerNFKC130("unify_hyphen_and_prolonged_sound_mark", true), \
                     NormalizerTable("column", "Normalizations.normalized")' \
      --default_tokenizer 'TokenNgram("loose_symbol", true, "loose_blank", true)'
    column_create TelsIndex tel_index COLUMN_INDEX|WITH_SECTION Tels tel
    
    load --table Tels
    [
    {"tel": "03-4S-1234"}
    {"tel": "03-45-9876"}
    ]
    
    select --table Tels \
      --filter 'tel @ "03-45-1234"'
    [
      [
        0,
        1625227424.560146,
        0.0001730918884277344
      ],
      [
        [
          [
            1
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "tel",
              "ShortText"
            ]
          ],
          [
            1,
            "03-4S-1234"
          ]
        ]
      ]
    ]
    

    既存のノーマライザーでは、このようなケースには対応できませんでしたが、このリリースから既存のノーマライザーと NormalizerTable を組み合わせることで、このようなケースにも対応できます。

  • [query_parallel_or][query] シーケンシャルサーチのしきい値をカスタマイズできるようにしました。

    以下のオプションを使うことで、シーケンシャルサーチを使うかどうかのしきい値をクエリーごとにカスタマイズできます。

    • {"max_n_enough_filtered_records": xx}

      max_n_enough_filtered_records は、レコード数を指定します。 query または、 query_parallel_or で、この値以下までレコードが絞り込めそうな場合、シーケンシャルサーチを使います。

    • {"enough_filtered_ratio": x.x}

      enough_filtered_ratio は、全体に占める割合を指定します。 query または、 query_parallel_or で、この割合以下までレコードが絞り込めそうな場合、シーケンシャルサーチを使います。例えば、 {"enough_filtered_ratio": 0.5} とした場合、 query または query_parallel_or で全体の半分まで絞り込めそうな場合はシーケンシャルサーチを使います。

    具体的には以下の通りです。

    table_create Products TABLE_NO_KEY
    column_create Products name COLUMN_SCALAR ShortText
    
    table_create Terms TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
    column_create Terms products_name COLUMN_INDEX Products name
    
    load --table Products
    [
    ["name"],
    ["Groonga"],
    ["Mroonga"],
    ["Rroonga"],
    ["PGroonga"],
    ["Ruby"],
    ["PostgreSQL"]
    ]
    
    select \
      --table Products \
      --filter 'query("name", "r name:Ruby", {"enough_filtered_ratio": 0.5})'
    
    table_create Products TABLE_NO_KEY
    column_create Products name COLUMN_SCALAR ShortText
    
    table_create Terms TABLE_PAT_KEY ShortText --normalizer NormalizerAuto
    column_create Terms products_name COLUMN_INDEX Products name
    
    load --table Products
    [
    ["name"],
    ["Groonga"],
    ["Mroonga"],
    ["Rroonga"],
    ["PGroonga"],
    ["Ruby"],
    ["PostgreSQL"]
    ]
    
    select \
      --table Products \
      --filter 'query("name", "r name:Ruby", {"max_n_enough_filtered_records": 10})'
    
  • [between][in_values] シーケンシャルサーチのしきい値をカスタマイズできるようにしました。

    [between] と [in_values] は、検索対象のレコードが十分に絞り込まれている時に、シーケンシャルサーチに切り替える機能があります。

    GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO / GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO の値は、Groongaがシーケンシャルサーチを実行するかインデックスを使った検索をするかのしきい値として使われます。

    今までは、以下の環境変数でのみカスタマイズ可能でした。

    in_values():

    # Don't use auto sequential search
    GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO=-1
    # Set threshold to 0.02
    GRN_IN_VALUES_TOO_MANY_INDEX_MATCH_RATIO=0.02
    

    between():

    # Don't use auto sequential search
    GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO=-1
    # Set threshold to 0.02
    GRN_BETWEEN_TOO_MANY_INDEX_MATCH_RATIO=0.02
    

    環境変数によるカスタマイズは、すべてのクエリーに対して適用されますが、この機能を使うことで、クエリーごとにしきい値を指定できます。

    具体的には以下の通りです。 {"too_many_index_match_ratio": x.xx} オプションでしきい値を指定できます。このオプションの値の型は double 型です。

    table_create Memos TABLE_HASH_KEY ShortText
    column_create Memos timestamp COLUMN_SCALAR Time
    
    table_create Times TABLE_PAT_KEY Time
    column_create Times memos_timestamp COLUMN_INDEX Memos timestamp
    
    load --table Memos
    [
    {"_key": "001", "timestamp": "2014-11-10 07:25:23"},
    {"_key": "002", "timestamp": "2014-11-10 07:25:24"},
    {"_key": "003", "timestamp": "2014-11-10 07:25:25"},
    {"_key": "004", "timestamp": "2014-11-10 07:25:26"},
    {"_key": "005", "timestamp": "2014-11-10 07:25:27"},
    {"_key": "006", "timestamp": "2014-11-10 07:25:28"},
    {"_key": "007", "timestamp": "2014-11-10 07:25:29"},
    {"_key": "008", "timestamp": "2014-11-10 07:25:30"},
    {"_key": "009", "timestamp": "2014-11-10 07:25:31"},
    {"_key": "010", "timestamp": "2014-11-10 07:25:32"},
    {"_key": "011", "timestamp": "2014-11-10 07:25:33"},
    {"_key": "012", "timestamp": "2014-11-10 07:25:34"},
    {"_key": "013", "timestamp": "2014-11-10 07:25:35"},
    {"_key": "014", "timestamp": "2014-11-10 07:25:36"},
    {"_key": "015", "timestamp": "2014-11-10 07:25:37"},
    {"_key": "016", "timestamp": "2014-11-10 07:25:38"},
    {"_key": "017", "timestamp": "2014-11-10 07:25:39"},
    {"_key": "018", "timestamp": "2014-11-10 07:25:40"},
    {"_key": "019", "timestamp": "2014-11-10 07:25:41"},
    {"_key": "020", "timestamp": "2014-11-10 07:25:42"},
    {"_key": "021", "timestamp": "2014-11-10 07:25:43"},
    {"_key": "022", "timestamp": "2014-11-10 07:25:44"},
    {"_key": "023", "timestamp": "2014-11-10 07:25:45"},
    {"_key": "024", "timestamp": "2014-11-10 07:25:46"},
    {"_key": "025", "timestamp": "2014-11-10 07:25:47"},
    {"_key": "026", "timestamp": "2014-11-10 07:25:48"},
    {"_key": "027", "timestamp": "2014-11-10 07:25:49"},
    {"_key": "028", "timestamp": "2014-11-10 07:25:50"},
    {"_key": "029", "timestamp": "2014-11-10 07:25:51"},
    {"_key": "030", "timestamp": "2014-11-10 07:25:52"},
    {"_key": "031", "timestamp": "2014-11-10 07:25:53"},
    {"_key": "032", "timestamp": "2014-11-10 07:25:54"},
    {"_key": "033", "timestamp": "2014-11-10 07:25:55"},
    {"_key": "034", "timestamp": "2014-11-10 07:25:56"},
    {"_key": "035", "timestamp": "2014-11-10 07:25:57"},
    {"_key": "036", "timestamp": "2014-11-10 07:25:58"},
    {"_key": "037", "timestamp": "2014-11-10 07:25:59"},
    {"_key": "038", "timestamp": "2014-11-10 07:26:00"},
    {"_key": "039", "timestamp": "2014-11-10 07:26:01"},
    {"_key": "040", "timestamp": "2014-11-10 07:26:02"},
    {"_key": "041", "timestamp": "2014-11-10 07:26:03"},
    {"_key": "042", "timestamp": "2014-11-10 07:26:04"},
    {"_key": "043", "timestamp": "2014-11-10 07:26:05"},
    {"_key": "044", "timestamp": "2014-11-10 07:26:06"},
    {"_key": "045", "timestamp": "2014-11-10 07:26:07"},
    {"_key": "046", "timestamp": "2014-11-10 07:26:08"},
    {"_key": "047", "timestamp": "2014-11-10 07:26:09"},
    {"_key": "048", "timestamp": "2014-11-10 07:26:10"},
    {"_key": "049", "timestamp": "2014-11-10 07:26:11"},
    {"_key": "050", "timestamp": "2014-11-10 07:26:12"}
    ]
    
    select Memos \
      --filter '_key == "003" && \
                between(timestamp, \
                        "2014-11-10 07:25:24", \
                        "include", \
                        "2014-11-10 07:27:26", \
                        "exclude", \
                        {"too_many_index_match_ratio": 0.03})'
    
    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 \
      --filter '_id >= 3 && \
                in_values(tag, \
                         "Groonga", \
                         {"too_many_index_match_ratio": 0.7})' \
      --output_columns _id,_score,_key,tag
    
  • [between] GRN_EXPR_OPTIMIZE=yes をサポートしました。

    between() で、条件式の評価順序の最適化をサポートしました。

  • [query_parallel_or][query] match_columns を vector で指定できるようにしました。[GitHub#1238][naoaさんがパッチ提供]

    以下のように、 queryquery_parallel_ormatch_columns に vector を使えます。

    table_create Users TABLE_NO_KEY
    column_create Users name COLUMN_SCALAR ShortText
    column_create Users memo COLUMN_SCALAR ShortText
    column_create Users tag COLUMN_SCALAR ShortText
    
    table_create Terms TABLE_PAT_KEY ShortText \
      --default_tokenizer TokenNgram \
      --normalizer NormalizerNFKC130
    column_create Terms name COLUMN_INDEX|WITH_POSITION Users name
    column_create Terms memo COLUMN_INDEX|WITH_POSITION Users memo
    column_create Terms tag COLUMN_INDEX|WITH_POSITION Users tag
    
    load --table Users
    [
    {"name": "Alice", "memo": "Groonga user", "tag": "Groonga"},
    {"name": "Bob",   "memo": "Rroonga user", "tag": "Rroonga"}
    ]
    
    select Users \
      --output_columns _score,name \
      --filter 'query(["name * 100", "memo", "tag * 10"], \
                      "Alice OR Groonga")'
    
  • [select] 前方一致検索でセクションと重みをサポートしました。[GitHub#1240][naoaさんがパッチ提供]

    前方一致検索でマルチカラムインデックスと、スコアーの調整ができます。

    table_create Memos TABLE_NO_KEY
    column_create Memos title COLUMN_SCALAR ShortText
    column_create Memos tags COLUMN_VECTOR ShortText
    
    table_create Terms TABLE_PAT_KEY ShortText
    column_create Terms index COLUMN_INDEX|WITH_SECTION Memos title,tags
    
    load --table Memos
    [
    {"title": "Groonga", "tags": ["Groonga"]},
    {"title": "Rroonga", "tags": ["Groonga", "Rroonga", "Ruby"]},
    {"title": "Mroonga", "tags": ["Groonga", "Mroonga", "MySQL"]}
    ]
    
    select Memos \
      --match_columns "Terms.index.title * 2" \
      --query 'G*' \
      --output_columns title,tags,_score
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "title",
              "ShortText"
            ],
            [
              "tags",
              "ShortText"
            ],
            [
              "_score",
              "Int32"
            ]
          ],
          [
            "Groonga",
            [
              "Groonga"
            ],
            2
          ]
        ]
      ]
    ]
    
  • [grndb] grndb recover で使用したオブジェクトを即時閉じるようにしました。

    これにより、メモリ消費を抑制できます。おそらくパフォーマンスは低下していますが、許容可能な低下です。

    grndb check はまだ、使用したオブジェクトを即時閉じないので注意してください。

  • [query_parallel_or][query] 以下のように、 match_columnsscorer_tf_idf を指定できるようにしました。

    table_create Tags TABLE_HASH_KEY ShortText
    
    table_create Users TABLE_HASH_KEY ShortText
    column_create Users tags COLUMN_VECTOR Tags
    
    load --table Users
    [
    {"_key": "Alice",
     "tags": ["beginner", "active"]},
    {"_key": "Bob",
     "tags": ["expert", "passive"]},
    {"_key": "Chris",
     "tags": ["beginner", "passive"]}
    ]
    
    column_create Tags users COLUMN_INDEX Users tags
    
    select Users \
      --output_columns _key,_score \
      --sort_keys _id \
      --command_version 3 \
      --filter 'query_parallel_or("scorer_tf_idf(tags)", \
                                  "beginner active")'
    {
      "header": {
        "return_code": 0,
        "start_time": 0.0,
        "elapsed_time": 0.0
      },
      "body": {
        "n_hits": 1,
        "columns": [
          {
            "name": "_key",
            "type": "ShortText"
          },
          {
            "name": "_score",
            "type": "Float"
          }
        ],
        "records": [
          [
            "Alice",
            2.098612308502197
          ]
        ]
      }
    }
    
  • [query_expand] 展開後の語の重みを操作できるようにしました。

    展開後の語に対して、重みを指定できます。

    スコアーを増やしたい場合は、 > を使います。スコアーを減らしたい場合は、 < を指定します。

    数字でスコアーの量を指定できます。負の数も指定できます。

    table_create TermExpansions TABLE_NO_KEY
    column_create TermExpansions term COLUMN_SCALAR ShortText
    column_create TermExpansions expansions COLUMN_VECTOR ShortText
    
    load --table TermExpansions
    [
    {"term": "Rroonga", "expansions": ["Rroonga", "Ruby Groonga"]}
    ]
    
    query_expand TermExpansions "Groonga <-0.2Rroonga Mroonga" \
      --term_column term \
      --expanded_term_column expansions
    [[0,0.0,0.0],"Groonga <-0.2((Rroonga) OR (Ruby Groonga)) Mroonga"]
    
  • [httpd] バンドルしているnginxのバージョンを1.21.1に更新しました。

  • バンドルしているApache Arrowを5.0.0に更新しました。

  • [Ubuntu] Ubuntu 20.10 (Groovy Gorilla)サポートをやめました。

    • Ubuntu 20.10 は、2021年7月22日でEOLとなったためです。

修正#

  • [query_parallel_or][query] query_options とその他のオプションを指定すると、その他のオプションが無視される問題を修正しました。

    例えば、以下のケースでは、 "default_operator": "OR" オプションは無視されていました。

    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": "and"},
    {"content": "Good-bye"}
    ]
    
    select Memos \
      --filter 'query_parallel_or( \
                  "content", \
                  "Hello and", \
                  {"default_operator": "OR", \
                   "options": {"TokenFilterStopWord.enable": false}})' \
      --match_escalation_threshold -1 \
      --sort_keys -_score
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "content",
              "ShortText"
            ]
          ],
          [
            2,
            "Hello and Good-bye"
          ]
        ]
      ]
    ]
    

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

  • 多くのデータを削除し、同じデータを再度loadすることを繰り返すと、Groongaがヒットすべきレコードを返さないことがあります。

感謝#

  • naoaさん

11.0.4リリース - 2021-06-29#

改良#

  • [Normalizer] カスタマイズされたノーマライザーを使えるようになりました。

    この機能を使うためにノーマライズ用のテーブルを定義し、このテーブルを使ってノーマライズします。つまり、カスタマイズされたノーマライザーを使うことができます。

    例えば、以下の例では、 "S" を "5" に正規化するよう定義しています。Substitutions テーブルが正規化用のテーブルです。

    table_create Substitutions TABLE_PAT_KEY ShortText
    column_create Substitutions substituted COLUMN_SCALAR ShortText
    load --table Substitutions
    [
    {"_key": "S", "substituted": "5"}
    ]
    
    table_create TelLists TABLE_NO_KEY
    column_create TelLists tel COLUMN_SCALAR ShortText
    
    table_create Terms TABLE_HASH_KEY ShortText \
      --default_tokenizer TokenNgram \
      --normalizer 'NormalizerTable("column", "Substitutions.substituted", \
                                    "report_source_offset", true)'
    column_create Terms tel_index COLUMN_INDEX|WITH_POSITION TelLists tel
    
    load --table TelLists
    [
    {"tel": "03-4S-1234"}
    ]
    
    select TelLists --filter 'tel @ "03-45-1234"'
    [
      [
        0,
        1624686303.538532,
        0.001319169998168945
      ],
      [
        [
          [
            1
          ],
          [
            [
              "_id",
              "UInt32"
            ],
            [
              "tel",
              "ShortText"
            ]
          ],
          [
            1,
            "03-4S-1234"
          ]
        ]
      ]
    ]
    

    例えば、手書きの文字を取り込む際に誤認識されやすい語を定義できます。そうすることで、誤ったデータを正規化して正しいデータにできます。

    この正規化用のテーブルを更新した場合は、インデックスの再構築が必要なことに注意してください。

  • 新しいコマンド object_warm を追加しました。

    このコマンドは、GroongaのDBをOSのページキャッシュに乗せます。

    OS起動後、Groongaを一度も起動していない場合、GroongaのDBはOSのページキャッシュ上に存在しません。そのため、Groongaに対する最初の操作は遅くなります。

    予めこのコマンドを実行した場合、Groongaへの最初の操作は速くなります。Linuxでは、 cat *.db > dev/null で同等のことができますが、Windowsでは、いままで、同様のことはできませんでした。

    このコマンドを使うことで、LinuxでもWindowsでもGroongaのDBをOSのページキャッシュへ乗せることができます。また、テーブル、カラム、インデックス単位でも同様のことができます。したがって、よく使うテーブルやカラム、インデックスのみをOSのページキャッシュに乗せることができます。

    このコマンドは、以下のように様々な対象に対して実行できます。

    • object_warm --name index_name と指定した場合は、指定したインデックスがOSのページキャッシュへ転送されます。

    • object_warm --name column_name と指定した場合は、指定したカラムがOSののページキャッシュへ転送されます。

    • object_warm --name table_name と指定した場合は、指定したテーブルをOSのページキャッシュへ転送します。

    • object_warm と指定した場合は、GroongaのDB全体がOSのページキャッシュへ転送されます。

    ただ、メモリーに空きスペースが無い場合は、このコマンドは効果がないことに注意してください。

  • [select] --filter 内で特定のレコードのスコアーを調整できるようにしました。

    *~ という演算子を使うことで、特定のレコードのスコアーを調整できます。*~&&|| と同じ論理演算子です。したがって、 &&|| と同じように使えます。*~ のデフォルトの重みは -1 です。

    したがって、例えば、 'content @ "Groonga" *~ content @ "Mroonga"' は以下の操作を意味します。

    1. 'content @ "Groonga"content @ "MySQL" にマッチしたレコードを抽出します。

    2. 以下のようにスコアーを追加します。

      1. 'content @ "Groonga" のスコアーを計算します。

      2. content @ "Mroonga"' のスコアーを計算します。

      3. bのスコアーを -1 倍します。

      4. このレコードのスコアーは a + b です。したがって、 aのスコアー 1 で bのスコアーが1 の場合、このレコードのスコアーは 1 + (1 * -1) = 0 です。

    また、 *~${score_quantity} とすることで、スコアーの量を指定できます。

    具体的には、 以下の条件( 'content @ "Groonga" *~2.5 content @ "MySQL"' ) にマッチしたレコードのスコアーを調整します。

    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
    column_create Terms index COLUMN_INDEX|WITH_POSITION Memos content
    
    load --table Memos
    [
    {"content": "Groonga is a full text search engine."},
    {"content": "Rroonga is the Ruby bindings of Groonga."},
    {"content": "Mroonga is a MySQL storage engine based of Groonga."}
    ]
    
    select Memos \
      --command_version 3 \
      --filter 'content @ "Groonga" *~2.5 content @ "Mroonga"' \
      --output_columns 'content, _score' \
      --sort_keys -_score,_id
    {
      "header": {
        "return_code": 0,
        "start_time": 1624605205.641078,
        "elapsed_time": 0.002965450286865234
      },
      "body": {
        "n_hits": 3,
        "columns": [
          {
            "name": "content",
            "type": "ShortText"
          },
          {
            "name": "_score",
            "type": "Float"
          }
        ],
        "records": [
          [
            "Groonga is a full text search engine.",
            1.0
          ],
          [
            "Rroonga is the Ruby bindings of Groonga.",
            1.0
          ],
          [
            "Mroonga is a MySQL storage engine based of Groonga.",
            -1.5
          ]
        ]
      }
    }
    

    adjuster を使っても同様のことができます。adjuster を使う場合、アプリケーション上で、 --filter 条件と --adjuster 条件を作る必要がありますが、この改良で、 --filter 条件のみを作成すればよくなりました。

    以下のように、 query() を使って、filter条件を記述することもできます。

    • --filter 'content @ "Groonga" *~2.5 content @ "Mroonga"'

  • [select] 重み付き && をサポートしました。

    *<*> を使うことで、重み付きの && を使えます。*< のデフォルトの重みは 0.5です。 *> のデフォルトの重みは 2.0 です。

    *<${score_quantity}*>${score_quantity} とすることで、スコアーの量を指定できます。また、 *<${score_quantity} と指定した場合は、 ${score_quantity} の正負の符号が反転します。

    例えば、 'content @ "Groonga" *<2.5 query("content", "MySQL")' は以下の操作を意味します。

    1. 'content @ "Groonga"content @ "MySQL" にマッチしたレコードを抽出します。

    2. 以下のようにスコアーを追加します。

      1. 'content @ "Groonga" のスコアーを計算します。

      2. query("content", "MySQL") のスコアーを計算します。

      3. bのスコアーは、 *< によって -2.5倍されます。

      4. このレコードのスコアーは a + b です。したがって、 aのスコアー 1 で bのスコアーが1 の場合、このレコードのスコアーは 1 + (1 * -2.5) = −1.5 です。

    具体的には、 以下の条件( 'content @ "Groonga" *~2.5 query("content", "MySQL")' にマッチしたレコードのスコアーを調整します。

    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
    column_create Terms index COLUMN_INDEX|WITH_POSITION Memos content
    
    load --table Memos
    [
    {"content": "Groonga is a full text search engine."},
    {"content": "Rroonga is the Ruby bindings of Groonga."},
    {"content": "Mroonga is a MySQL storage engine based of Groonga."}
    ]
    
    select Memos \
      --command_version 3 \
      --filter 'content @ "Groonga" *<2.5 query("content", "Mroonga")' \
      --output_columns 'content, _score' \
      --sort_keys -_score,_id
    {
      "header": {
        "return_code": 0,
        "start_time": 1624605205.641078,
        "elapsed_time": 0.002965450286865234
      },
      "body": {
        "n_hits": 3,
        "columns": [
          {
            "name": "content",
            "type": "ShortText"
          },
          {
            "name": "_score",
            "type": "Float"
          }
        ],
        "records": [
          [
            "Groonga is a full text search engine.",
            1.0
          ],
          [
            "Rroonga is the Ruby bindings of Groonga.",
            1.0
          ],
          [
            "Mroonga is a MySQL storage engine based of Groonga.",
            -1.5
          ]
        ]
      }
    }
    
  • [ログ] 標準出力、標準エラー出力への出力をサポートしました。

    [プロセスログ] と [クエリーログ] が標準出力と標準エラー出力への出力をサポートしました。

    • --log-path ---query-log-path - と指定した場合、Groongaはログを標準出力に出力します。

    • --log-path +--query-log-path + と指定した場合、Groongaはログを標準エラー出力に出力します。

    [プロセスログ] はGroongaの動作全てに関することのログです。 [クエリーログ] は、クエリー処理に関することだけのログです。

    この機能はDocker上でGroongaを実行する際に有用です。Dockerは標準で標準出力と標準エラー出力を記録する機能を持っています。したがって、Groongaのログを取得するために、Dockerの環境にログインする必要がなくなります。

    例えば、この機能は、以下のようなケースで有用です。

    • Docker上のGroongaのスロークエリーを解析したい場合。

      Groonga起動時に --query-log-path - と指定している場合、以下のコマンドを実行するだけでスロークエリーを解析できます。

      • docker logs ${container_name} | groonga-query-log-analyze

    このように、 Groonga上のDockerから出力したクエリーログを使って、簡単にスロークエリの解析ができます。

  • [ドキュメント] string_substring に不足している内容を追加しました。[Github#1209][Takashi Hashidaさんがパッチ提供]

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

  • *<*> は、filter条件の右辺に query() を使う時のみ有効です。もし、以下のように指定した場合、 *<*>&& として機能します。

    • 'content @ "Groonga" *< content @ "Mroonga"'

感謝#

  • Takashi Hashidaさん

11.0.3リリース - 2021-05-29#

改良#

  • [query] クエリー毎に TokenFilterStem を無効にできるようになりました。

    • TokenFilterStem は語幹を使った検索ができます。例えば developdevelopingdevelopeddevelops も、すべてステミングすると develop になります。そのため、 develops というクエリーで developdevelopingdeveloped も検索できます。

    • 今回のリリースでは、以下のように特定のクエリーでのみ TokenFilterStem を無効にして検索できるようになりました。

      plugin_register token_filters/stem
      
      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 'TokenFilterStem("keep_original", true)'
      column_create Terms memos_content COLUMN_INDEX|WITH_POSITION Memos content
      
      load --table Memos
      [
      {"content": "I develop Groonga"},
      {"content": "I'm developing Groonga"},
      {"content": "I developed Groonga"}
      ]
      
      select Memos \
        --match_columns content \
        --query '"developed groonga"' \
        --query_options '{"TokenFilterStem.enable": false}'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              1
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "content",
                "ShortText"
              ]
            ],
            [
              3,
              "I developed Groonga"
            ]
          ]
        ]
      ]
      
    • この機能は、通常は語幹を使った検索がしたいが、時々、以下のように(ステミングされていない)正確な語で検索したいときに有用です。

      • ステミングされた語を使った検索だとGroongaが大量の検索結果を返す場合。

      • TokenFilerStem が間違ったステミング結果を返す場合。

      • (ステミングされていない)正確な語を含むレコードのみを検索したい場合。

  • [query] クエリー毎に TokenFilterStopWord を無効にできるようになりました。

    • TokenFilterStopWord は、予め登録したストップワードを検索から除外します。これは、 andis などの頻出語を無視することで検索ノイズを減らすために使います。

    • ただ、ときどき、特定のクエリーでのみこれらの語を含めて検索したいときがあります。今回のリリースでは、以下のように特定のクエリーでのみ TokenFilterStopWord を無効にして検索できるようになりました。

      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 \
        --match_columns content \
        --query "Hello and" \
        --query_options '{"TokenFilterStopWord.enable": false}' \
        --match_escalation_threshold -1 \
        --sort_keys -_score
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              1
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "content",
                "ShortText"
              ]
            ],
            [
              2,
              "Hello and Good-bye"
            ]
          ]
        ]
      ]
      
    • 上記の例では、 --query-options を使って、 TokenFilterStopWord.enable を指定していますが、以下のように {"options": {"TokenFilterStopWord.enable": false}} を使っても指定できます。

      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("content", \
                        "Hello and", \
                        {"options": {"TokenFilterStopWord.enable": false}})' \
        --match_escalation_threshold -1 \
        --sort_keys -_score
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              1
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "content",
                "ShortText"
              ]
            ],
            [
              2,
              "Hello and Good-bye"
            ]
          ]
        ]
      ]
      
    • この機能は、よく使われる語を含めて検索しないとGroongaが正しい結果を返さない時に便利です。(例えば、曲名や店名等を検索する場合です。)

  • [ノーマライザー][NormalizerNFKC] 新しいオプション remove_new_line を追加しました。

    • データを格納するテーブルのキーを正規化したい場合、そのテーブルにノーマライザーを設定しますが、通常ノーマライザーは改行を削除します。

    • ノーマライザーが改行を削除してしまうと、Groongaは改行のみのキーを扱えません。

    • このオプションを使うことで、改行のみのデータをキーとして登録できます。

  • [string_slice] 新しい関数 string_slice() を追加しました。 [Github#1177][Takashi Hashidaさんがパッチ提供]

    • string_slice() は、文字列の部分文字列を抽出します。

    • この関数を使うには、 functions/string プラグインの登録が必要です。

    • 以下のように、引数によって2つの異なる抽出方法を使えます。

      • 位置を使った抽出:

        plugin_register functions/string
        table_create Memos TABLE_HASH_KEY ShortText
        
        load --table Memos
        [
          {"_key": "Groonga"}
        ]
        select Memos --output_columns '_key, string_slice(_key, 2, 3)'
        [
          [
            0,
            1337566253.89858,
            0.000355720520019531
          ],
          [
            [
              [
                1
              ],
              [
                [
                  "_key",
                  "ShortText"
                ],
                [
                  "string_slice",
                  null
                ]
              ],
              [
                "Groonga",
                "oon"
              ]
            ]
          ]
        ]
        
      • 正規表現を使った抽出:

        plugin_register functions/string
        table_create Memos TABLE_HASH_KEY ShortText
        
        load --table Memos
        [
          {"_key": "Groonga"}
        ]
        select Memos --output_columns '_key, string_slice(_key, "(Gro+)(.*)", 2)'
        [
          [p
            0,
            1337566253.89858,
            0.000355720520019531
          ],
          [
            [
              [
                1
              ],
              [
                [
                  "_key",
                  "ShortText"
                ],
                [
                  "string_slice",
                  null
                ]
              ],
              [
                "Groonga",
                "nga"
              ]
            ]
          ]
        ]
        
  • [Ubuntu] Ubuntu 16.04 LTS (Xenial Xerus)のサポートをやめました。

  • Visual Studio 用の EditorConfig を追加しました。[GitHub#1191][Takashi Hashidaさんがパッチ提供]

    • 多くの設定は、Visual Studio 専用です。

  • [httpd] バンドルしているnginxのバージョンを1.20.1に更新しました。

    • CVE-2021-23017のセキュリティの修正が含まれています。

修正#

  • オプションをサポートしているトークナイザーやノーマライザー、トークンフィルターが使われている際、多くの検索クエリーを送信するとGroongaが応答を返さなくなることがある問題を修正しました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。

感謝#

  • Takashi Hashidaさん

11.0.2リリース - 2021-05-10#

改良#

  • [Documentation] ruby_load コマンドのリファレンスを削除しました。 [GitHub#1172][Anthony M. Cookさんがパッチ提供]

    • このコマンドはすでに削除されているためです。

  • [Debian GNU/Linux] Debian 11(Bullseye) をサポートしました。

  • [select] --post_filter をサポートしました。

    • 以下のように、 filtered ステージの動的カラムに対して post_filter を使ってフィルターできます。

      table_create Items TABLE_NO_KEY
      column_create Items price COLUMN_SCALAR UInt32
      
      load --table Items
      [
      {"price": 100},
      {"price": 150},
      {"price": 200},
      {"price": 250},
      {"price": 300}
      ]
      
      select Items \
        --filter "price >= 150" \
        --columns[price_with_tax].stage filtered \
        --columns[price_with_tax].type UInt32 \
        --columns[price_with_tax].flags COLUMN_SCALAR \
        --columns[price_with_tax].value "price * 1.1" \
        --post_filter "price_with_tax <= 250"
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              2
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "price_with_tax",
                "UInt32"
              ],
              [
                "price",
                "UInt32"
              ]
            ],
            [
              2,
              165,
              150
            ],
            [
              3,
              220,
              200
            ]
          ]
        ]
      ]
      
  • [select] --slices[].post_filter をサポートしました。

    • 以下のように、 --slices[].filter の条件でフィルターされた結果に対して post_filter を使えます。

      table_create Items TABLE_NO_KEY
      column_create Items price COLUMN_SCALAR UInt32
      
      load --table Items
      [
      {"price": 100},
      {"price": 200},
      {"price": 300},
      {"price": 1000},
      {"price": 2000},
      {"price": 3000}
      ]
      
      select Items \
        --slices[expensive].filter 'price >= 1000' \
        --slices[expensive].post_filter 'price < 3000'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              6
            ],
            [
              [
                "_id",
                "UInt32"
              ],
              [
                "price",
                "UInt32"
              ]
            ],
            [
              1,
              100
            ],
            [
              2,
              200
            ],
            [
              3,
              300
            ],
            [
              4,
              1000
            ],
            [
              5,
              2000
            ],
            [
              6,
              3000
            ]
          ],
          {
            "expensive": [
              [
                2
              ],
              [
                [
                  "_id",
                  "UInt32"
                ],
                [
                  "price",
                  "UInt32"
                ]
              ],
              [
                4,
                1000
              ],
              [
                5,
                2000
              ]
            ]
          }
        ]
      ]
      
  • [select] --sort_keys 内に式を記述できるようになりました。

    • --sort_keys に式を記述できます。

      • 存在しないキーが sort_keys の式に含まれていた場合、それらは、無視され警告がログに出力されます。

    • これによって、例えば、 --sort_keysVECTOR_COLUMN の要素を指定し、 VECTOR_COLUMN の要素で結果をソートできます。

    • 以前のバージョンでも動的カラムを使えば、 VECTOR COLUMN の要素で結果をソートできましたが、この機能によって、動的カラムを使わずに VECTOR_COLUMN の要素で結果をソートできます。

      table_create Values TABLE_NO_KEY
      column_create Values numbers COLUMN_VECTOR Int32
      load --table Values
      [
      {"numbers": [127, 128, 129]},
      {"numbers": [126, 255]},
      {"numbers": [128, -254]}
      ]
      select Values --sort_keys 'numbers[1]' --output_columns numbers
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              3
            ],
            [
              [
                "numbers",
                "Int32"
              ]
            ],
            [
              [
                128,
                -254
              ]
            ],
            [
              [
                127,
                128,
                129
              ]
            ],
            [
              [
                126,
                255
              ]
            ]
          ]
        ]
      ]
      
  • [トークンフィルター] オプションをつけた複数のトークンフィルターを使えるようにしました。

    • --token_filters 'TokenFilterStopWord("column", "ignore"), TokenFilterNFKC130("unify_kana", true)' のように複数のトークンフィルターを指定できます。 [Github#mroonga/mroonga#399][MASUDA Kazuhiroさんが報告]

  • [query] 複雑な式で result_set ステージの動的カラムを扱えるようにしました。

    • 複雑な式とは、以下のように一時的な内部結果セットが必要な式です。

      '(true && query("name * 10", "ali", {"score_column": "ali_score"})) || \
       (true && query("name * 2", "li", {"score_column": "li_score"}))'
      
      • 上記の式では、 true の評価結果を格納するために一時的な結果セットを使用します。

      • したがって、例えば、以下の式では、式の中で result_set ステージの動的カラムの値を使えます。以下の式では、一時的な内部結果セットが必要ないためです。

        '(query("name * 10", "ali", {"score_column": "ali_score"})) || \
         (query("name * 2", "li", {"score_column": "li_score"}))'
        
    • 今回のリリースでは、以下のように li_score に値を設定できます。(以前のバージョンでは、2番めの式が動的カラムの値を取得出来なかったため、 li_score の値は 0 になっていました。)

      table_create Users TABLE_NO_KEY
      column_create Users name COLUMN_SCALAR ShortText
      
      table_create Lexicon TABLE_HASH_KEY ShortText \
        --default_tokenizer TokenBigramSplitSymbolAlphaDigit \
        --normalizer NormalizerAuto
      column_create Lexicon users_name COLUMN_INDEX|WITH_POSITION Users name
      
      load --table Users
      [
      {"name": "Alice"},
      {"name": "Alisa"},
      {"name": "Bob"}
      ]
      
      select Users \
        --columns[ali_score].stage result_set \
        --columns[ali_score].type Float \
        --columns[ali_score].flags COLUMN_SCALAR \
        --columns[li_score].stage result_set \
        --columns[li_score].type Float \
        --columns[li_score].flags COLUMN_SCALAR \
        --output_columns name,_score,ali_score,li_score \
        --filter '(true && query("name * 10", "ali", {"score_column": "ali_score"})) || \
                  (true && query("name * 2", "li", {"score_column": "li_score"}))'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              2
            ],
            [
              [
                "name",
                "ShortText"
              ],
              [
                "_score",
                "Int32"
              ],
              [
                "ali_score",
                "Float"
              ],
              [
                "li_score",
                "Float"
              ]
            ],
            [
              "Alice",
              14,
              10.0,
              2.0
            ],
            [
              "Alisa",
              14,
              10.0,
              2.0
            ]
          ]
        ]
      ]
      
    • 以下のように、 result_set ステージの動的ベクターカラムも扱えるようにしました。

      table_create Users TABLE_NO_KEY
      column_create Users name COLUMN_SCALAR ShortText
      
      table_create Lexicon TABLE_HASH_KEY ShortText \
        --default_tokenizer TokenBigramSplitSymbolAlphaDigit \
        --normalizer NormalizerAuto
      column_create Lexicon users_name COLUMN_INDEX|WITH_POSITION Users name
      
      load --table Users
      [
      {"name": "Alice"},
      {"name": "Alisa"},
      {"name": "Bob"}
      ]
      
      select Users \
        --columns[tags].stage result_set \
        --columns[tags].type ShortText \
        --columns[tags].flags COLUMN_VECTOR \
        --output_columns name,tags \
        --filter '(true && query("name", "al", {"tags": ["al"], "tags_column": "tags"})) || \
                  (true && query("name", "sa", {"tags": ["sa"], "tags_column": "tags"}))'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              2
            ],
            [
              [
                "name",
                "ShortText"
              ],
              [
                "tags",
                "ShortText"
              ]
            ],
            [
              "Alice",
              [
                "al"
              ]
            ],
            [
              "Alisa",
              [
                "al",
                "sa"
              ]
            ]
          ]
        ]
      ]
      
      • 動的ベクターカラムを使う場合、格納する値は各要素が追加された値になります。

  • [Ubuntu] Ubuntu 21.04 (Hirsute Hippo)をサポートしました。

  • [httpd] バンドルしているnginxのバージョンを1.19.10に更新しました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

  • [ブラウザーベースの管理ツール] 現在Groongaには、レコード一覧の管理モードのチェックボックスにチェックを入れても、非管理モードに入力された検索クエリーが送信されるという問題があります。 [Github#1186][potiさんが報告]

感謝#

  • Anthony M. Cookさん

  • MASUDA Kazuhiroさん

  • potiさん

11.0.1リリース - 2021-03-31#

改良#

  • [Debian GNU/Linux] ARM64向けのパッケージをサポートしました。

  • [select] キーワードごとに重みをカスタマイズできるようにしました。

    • 今まで、スコアーを調整するには、すべてのキーワードに対して <> を指定する必要がありました。デフォルトのスコアの重み(1)より、デフォルトの重みの調整量(6 または 4)のほうが大きいためです。

      • 例えば、A <B では、 "A" の重みは1、 "B" の重みは4になります。デクリメントされていない "A" の重み(1)より、デクリメントされた "B" の重み(4)のほうが大きくなります。これは、期待した動作ではありません。"B" に "A" より小さい重みを使うためには、 >A <B と指定する必要があります。>A <B では、 "A" の重みは6、 "B" の重みは4になります。

    • 今回のリリースから、対象のキーワードに <${WEIGHT} または >${WEIGHT} と指定するだけで、キーワードごとに重みの調整量をカスタマイズできます。例えば、 A <0.1B では、 "A" の重みは1、 "B" の重みは0.9になります。("B" の重みを0.1デクリメントしています。)

    • ただし、これらの形式(>${WEIGHT}..., <${WEIGHT}..., and ~${WEIGHT}...)は互換性が無いことに注意してください。

  • [select] Apache Arrow形式で FloatFloat32 の値を出力できるようにしました。

    • 例えば、以下のように出力します。

    table_create Data TABLE_NO_KEY
    column_create Data float COLUMN_SCALAR Float
    
    load --table Data
    [
    {"float": 1.1}
    ]
    
    select Data \
      --command_version 3 \
      --output_type apache-arrow
    
      return_code: int32
      start_time: timestamp[ns]
      elapsed_time: double
      -- metadata --
      GROONGA:data_type: metadata
       return_code                    start_time       elapsed_time
      0                  0     1970-01-01T09:00:00+09:00           0.000000
      ========================================
      _id: uint32
      float: double
      -- metadata --
      GROONGA:n_hits: 1
       _id          float
      0          1       1.100000
    
  • [select] 結果出力時に、インデックスカラム経由で参照先のデータを取得できるようになりました。

    • 今までは、 出力値に index_column.xxx のように指定すると、Groongaは意図しない値を返していました。例えば以下の例では、 --columns[tags].value purchases.tag の値は、 ["apple",["many"]],["banana",["man"]],["cacao",["man"]] になりました。このケースでは、期待される値は、 ["apple",["man","many"]],["banana",["man"]],["cacao",["woman"]] でした。今回のリリースから、以下のように、インデックスカラム経由で参照先の正しい値を取得できます。

      table_create Products TABLE_PAT_KEY ShortText
      
      table_create Purchases TABLE_NO_KEY
      column_create Purchases product COLUMN_SCALAR Products
      column_create Purchases tag COLUMN_SCALAR ShortText
      
      column_create Products purchases COLUMN_INDEX Purchases product
      
      load --table Products
      [
      {"_key": "apple"},
      {"_key": "banana"},
      {"_key": "cacao"}
      ]
      
      load --table Purchases
      [
      {"product": "apple",  "tag": "man"},
      {"product": "banana", "tag": "man"},
      {"product": "cacao",  "tag": "woman"},
      {"product": "apple",  "tag": "many"}
      ]
      
      select Products \
        --columns[tags].stage output \
        --columns[tags].flags COLUMN_VECTOR \
        --columns[tags].type ShortText \
        --columns[tags].value purchases.tag \
        --output_columns _key,tags
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              3
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "tags",
                "ShortText"
              ]
            ],
            [
              "apple",
              [
                "man",
                "many"
              ]
            ],
            [
              "banana",
              [
                "man"
              ]
            ],
            [
              "cacao",
              [
                "woman"
              ]
            ]
          ]
        ]
      ]
      
  • [select] ネストされたインデックスの一部として直接インデックスカラムを指定できるようになりました。

    • index_column.except_source_column を使ってフィルター後にソーステーブルを検索できます。例えば、以下の例では、検索時に comments.content を指定しています。この場合、最初に、このクエリは Comments テーブルの content カラムを全文検索し、次に Comments テーブルを検索した結果のレコードを参照する Articles テーブルのレコードを取得します。

      table_create Articles TABLE_HASH_KEY ShortText
      
      table_create Comments TABLE_NO_KEY
      column_create Comments article COLUMN_SCALAR Articles
      column_create Comments content COLUMN_SCALAR ShortText
      
      column_create Articles content COLUMN_SCALAR Text
      column_create Articles comments COLUMN_INDEX Comments article
      
      table_create Terms TABLE_PAT_KEY ShortText \
        --default_tokenizer TokenBigram \
        --normalizer NormalizerNFKC130
      column_create Terms articles_content COLUMN_INDEX|WITH_POSITION \
        Articles content
      column_create Terms comments_content COLUMN_INDEX|WITH_POSITION \
        Comments content
      
      load --table Articles
      [
      {"_key": "article-1", "content": "Groonga is fast!"},
      {"_key": "article-2", "content": "Groonga is useful!"},
      {"_key": "article-3", "content": "Mroonga is fast!"}
      ]
      
      load --table Comments
      [
      {"article": "article-1", "content": "I'm using Groonga too!"},
      {"article": "article-3", "content": "I'm using Mroonga!"},
      {"article": "article-1", "content": "I'm using PGroonga!"}
      ]
      
      select Articles --match_columns comments.content --query groonga \
        --output_columns "_key, _score, comments.content
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              1
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "_score",
                "Int32"
              ],
              [
                "comments.content",
                "ShortText"
              ]
            ],
            [
              "article-1",
              1,
              [
                "I'm using Groonga too!",
                "I'm using PGroonga!"
              ]
            ]
          ]
        ]
      ]
      
  • [load] オブジェクトリテラルを使って、参照先のレコードをロードできるようにしました。

    • 例えば、以下のように、 "key" : "[ { "key" : "value", ..., "key" : "value" } ]" のようなデータをロードできます。

      table_create Purchases TABLE_NO_KEY
      column_create Purchases item COLUMN_SCALAR ShortText
      column_create Purchases price COLUMN_SCALAR UInt32
      
      table_create Settlements TABLE_HASH_KEY ShortText
      column_create Settlements purchases COLUMN_VECTOR Purchases
      column_create Purchases settlements_purchases COLUMN_INDEX Settlements purchases
      
      load --table Settlements
      [
      {
        "_key": "super market",
        "purchases": [
           {"item": "apple", "price": 100},
           {"item": "milk",  "price": 200}
        ]
      },
      {
        "_key": "shoes shop",
        "purchases": [
           {"item": "sneakers", "price": 3000}
        ]
      }
      ]
      
    • この機能によって、参照カラムにJSONデータを追加しやすくなります。

    • 現状、この機能は、JSONの入力のみをサポートしています。

  • [load] JSON文字列で、参照先のレコードをロードできるようにしました。

    • 以下のように、JSONテキストを使ってソーステーブルから参照ベクターへデータをロードできます。

      table_create Purchases TABLE_HASH_KEY ShortText
      column_create Purchases item COLUMN_SCALAR ShortText
      column_create Purchases price COLUMN_SCALAR UInt32
      
      table_create Settlements TABLE_HASH_KEY ShortText
      column_create Settlements purchases COLUMN_VECTOR Purchases
      
      column_create Purchases settlements_purchases COLUMN_INDEX Settlements purchases
      
      load --table Settlements
      [
      {
        "_key": "super market",
        "purchases": "[{\"_key\": \"super market-1\", \"item\": \"apple\", \"price\": 100}, {\"_key\": \"super market-2\", \"item\": \"milk\",  \"price\": 200}]"
      },
      {
        "_key": "shoes shop",
        "purchases": "[{\"_key\": \"shoes shop-1\", \"item\": \"sneakers\", \"price\": 3000}]"
      }
      ]
      
      dump \
        --dump_plugins no \
        --dump_schema no
      load --table Purchases
      [
      ["_key","item","price"],
      ["super market-1","apple",100],
      ["super market-2","milk",200],
      ["shoes shop-1","sneakers",3000]
      ]
      
      load --table Settlements
      [
      ["_key","purchases"],
      ["super market",["super market-1","super market-2"]],
      ["shoes shop",["shoes shop-1"]]
      ]
      
      column_create Purchases settlements_purchases COLUMN_INDEX Settlements purchases
      
    • 現状、この機能は、ネストされた参照レコードをサポートしていません。

  • [Windows] time_classify_* 関数で UNIXエポック を扱えるようになりました。

    • Groongaは、現地時刻でタイムスタンプを扱っています。したがって、例えば日本でUNIXエポックを入力した場合、入力した時刻はUNIXエポックの9時間前になります。

    • WindowsのAPIはUNIXエポックより前の時間が入力されるとエラーになります。

    • 今回のリリースから、以下のようにUNIXエポックを time_classify_* 内で使えるように

      plugin_register functions/time
      
      table_create Timestamps TABLE_PAT_KEY Time
      load --table Timestamps
      [
      {"_key": 0},
      {"_key": "2016-05-06 00:00:00.000001"},
      {"_key": "2016-05-06 23:59:59.999999"},
      {"_key": "2016-05-07 00:00:00.000000"},
      {"_key": "2016-05-07 00:00:00.000001"},
      {"_key": "2016-05-08 23:59:59.999999"},
      {"_key": "2016-05-08 00:00:00.000000"}
      ]
      
      select Timestamps \
        --sortby _id \
        --limit -1 \
        --output_columns '_key, time_classify_day_of_week(_key)'
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              7
            ],
            [
              [
                "_key",
                "Time"
              ],
              [
                "time_classify_day_of_week",
                null
              ]
            ],
            [
              0.0,
              4
            ],
            [
              1462460400.000001,
              5
            ],
            [
              1462546799.999999,
              5
            ],
            [
              1462546800.0,
              6
            ],
            [
              1462546800.000001,
              6
            ],
            [
              1462719599.999999,
              0
            ],
            [
              1462633200.0,
              0
            ]
          ]
        ]
      ]
      
  • [query_parallel_or] クエリーを並行して実行できる新しい関数を追加しました。

    • query_parallel_or でクエリーを並行で処理するためにはApache Arrowが必要です。Apache Arrowが無い場合は、 query_parallel_or はクエリーをシーケンシャルに実行します。

    • query_parallel_or は、 match_columnsquery_string の組み合わせを平行に処理します。

    • query_parallel_or の構文は以下の通りです。:

      query_parallel_or(match_columns, query_string1,
                                       query_string2,
                                       .
                                       .
                                       .
                                       query_stringN,
                                       {"option": "value", ...})
      
  • [select] 存在しないソートキーを無視するようにしました。

    • 今まで、存在しないソートキーを指定したとき、Groongaはエラーを出力していましたが、今回のリリースから存在しないソートキーを無視します。(エラーを出力しなくなります。)

    • この機能は、一貫性のために実装しています。output_columns も無効な値を無視します。また、 sort_keys も無効な値のほとんどを無視します。

  • [select] drilldowns[].table で存在しないテーブルを無視します。 [GitHub#1169][naoaさんが報告]

    • 今まで、 drilldowns[].table で存在しないテーブルを指定したとき、Groongaはエラーを出力していましたが、今回のリリースから存在しないテーブルを無視します。(エラーを出力しなくなります。)

    • この機能は、一貫性のために実装しています。output_columns も無効な値を無視します。また、 sort_keys も無効な値のほとんどを無視します。

  • [httpd] バンドルしているnginxのバージョンを1.19.8に更新しました。

修正#

  • [reference_acquire] 参照の自動リリースが発生する前に、テーブルにカラムが追加されテーブルの参照が獲得されたときにGroongaがクラッシュする問題を修正しました。

    • 追加されたカラムの参照は獲得されませんが、自動リリースの対象になるためです。

  • [Windows] 別のスレッドで、他のバックトレースロギングプロセスが動作しているときに、新しくバックトレースロギングプロセスが開始されると、1つ以上のプロセスがSEGVのバックトレースの出力に失敗する問題を修正しました。

既知の問題#

  • 現在Groongaには、ベクターカラムに対してデータを大量に追加、削除、更新した際にデータが破損することがある問題があります。

感謝#

  • naoaさん

11.0.0リリース - 2021-02-09#

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

改良#

  • [select] ネストされたインデックス経由でスカラーカラムとベクターカラムの値を出力できるようになりました。

    • ネストされたインデックスとは、以下のような構造です。

      table_create Products TABLE_PAT_KEY ShortText
      
      table_create Purchases TABLE_NO_KEY
      column_create Purchases product COLUMN_SCALAR Products
      column_create Purchases tag COLUMN_SCALAR ShortText
      
      column_create Products purchases COLUMN_INDEX Purchases product
      
    • 上記の例では、 Products.purchases カラムは Purchases.product カラムのインデックスです。また、 Purchases.product カラムは、 Products テーブルへの参照です。

    • 今までは、ネストされたインデックス経由の検索は、期待した結果を返しませんでした。

    • 今までの結果は以下のようになっていました。 {"product": "apple",  "tag": "man"} が出力されていないことがわかります。

      table_create Products TABLE_PAT_KEY ShortText
      
      table_create Purchases TABLE_NO_KEY
      column_create Purchases product COLUMN_SCALAR Products
      column_create Purchases tag COLUMN_SCALAR ShortText
      
      column_create Products purchases COLUMN_INDEX Purchases product
      
      load --table Products
      [
      {"_key": "apple"},
      {"_key": "banana"},
      {"_key": "cacao"}
      ]
      
      load --table Purchases
      [
      {"product": "apple",  "tag": "man"},
      {"product": "banana", "tag": "man"},
      {"product": "cacao",  "tag": "woman"},
      {"product": "apple",  "tag": "many"}
      ]
      
      select Products \
        --output_columns _key,purchases.tag
      [
        [
          0,
          1612504193.380738,
          0.0002026557922363281
        ],
        [
          [
            [
              3
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "purchases.tag",
                "ShortText"
              ]
            ],
            [
              "apple",
              "many"
            ],
            [
              "banana",
              "man"
            ],
            [
              "cacao",
              "man"
            ]
          ]
        ]
      ]
      
    • このリリースから、結果は以下のようになります。 {"product": "apple",  "tag": "man"} が出力されているのがわかります。

      select Products \
        --output_columns _key,purchases.tag
      [
        [
          0,
          0.0,
          0.0
        ],
        [
          [
            [
              3
            ],
            [
              [
                "_key",
                "ShortText"
              ],
              [
                "purchases.tags",
                "Tags"
              ]
            ],
            [
              "apple",
              [
                [
                  "man",
                  "one"
                ],
                [
                  "child",
                  "many"
                ]
              ]
            ],
            [
              "banana",
              [
                [
                  "man",
                  "many"
                ]
              ]
            ],
            [
              "cacao",
              [
                [
                  "woman"
                ]
              ]
            ]
          ]
        ]
      ]
      
  • [Windows] Linux上のMinGWを使ってクロスコンパイルしていたWindows向けパッケージの提供をやめました。

    • おそらく、ほとんどの人がこのパッケージを使っていないためです。

    • 上記のパッケージはこれまで、以下のような名前で提供されていたものです。

      • groonga-x.x.x-x86.exe

      • groonga-x.x.x-x86.zip

      • groonga-x.x.x-x64.exe

      • groonga-x.x.x-x86.zip

    • これからは、以下のパッケージを使用してください。

      • groonga-latest-x86-vs2019-with-vcruntime.zip

      • groonga-latest-x64-vs2019-with-vcruntime.zip

    • 既に Microsoft Visual C++ Runtime Library がインストール済みのシステムの場合は、以下のパッケージを使用してください。

      • groonga-latest-x86-vs2019.zip

      • groonga-latest-x64-vs2019.zip

修正#

  • インデックス内のデータを大量に追加、削除、更新した際にインデックスが破損することがある問題を修正しました。

    • この問題は、インデックス内のデータを大量に削除しただけでも発生します。ただ、インデックスにデータを追加しただけでは発生しません。

    • この問題によって破損したインデックスは、インデックスを再構築することで修復できます。

    • この問題は、壊れたインデックスを参照しない限り発覚しません。したがって、既にインデックスが破損しているかもしれません。

    • [index_column_diff] コマンドを使うことで、インデックスが破損しているかどうかを確認できます。

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] TokenDocumentVectorTFIDFTokenDocumentVectorBM25 でトークンカラムをサポートしました。

    • インデックスカラムと同じソースを持つトークンカラムがある場合、これらのトークナイザーは、トークンカラムのトークン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"
              ]
            ]
          ]
        ]
      ]
      
    • TokenDocumentVectorTFIDFTokenDocumentVectorBM25 は、各トークンに対して重みをつけます。

  • 以下のケースのパフォーマンスを改善しました。

    • (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が空の vectoruvector を評価した時の動作を変更しました。

    • 空の vectoruvector は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_Bcustomers カラムの 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_pathsno を指定してください。

  • 新しい関数 string_toknize() を追加しました。

    • この関数は、第二引数に指定されたカラムの値を、第一引数に指定されたトークナイザーでトークナイズします。

  • [tokenizers] 新しいトークナイザー TokenDocumentVectorTFIDF を追加しました。(実験的)

    • このトークナイザーは、TF-IDFで文書ベクトルを自動で生成します。

  • [tokenizers] 新しいトークナイザー TokenDocumentVectorBM25 を追加しました。(実験的)

    • このトークナイザーは、BM25で文書ベクトルを自動で生成します。

  • [select] 同一センテンス内での、フレーズ近傍検索をサポートしました。

修正#

  • [load] 257個のカラムに対して load を実行すると load の応答が返らなくなる問題を修正しました。

    • この問題は、10.0.4以降で発生する可能性があります。

    • この問題は、 [a, b, c, ...] の形式でデータをロードした時にのみ発生します。

      • [{...}] を使ってデータをロードした場合は発生しません。

  • [MessagePack] float32の値を正しくアンパックできない問題を修正しました。

  • マルチカラムインデックス関連の問題を修正しました。

10.0.6リリース - 2020-08-29#

改良#

  • [logical_range_filter] 大きなデータの検索プランを改善しました。

    • 通常、 logical_range_filterlogical_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_htmlhighlight_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さんのパッチ提供]

    • 例えば、 以下のように _scoreaggregator_* の対象にできます。

      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形式で出力する際に NaNInfinity-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_acquirereference_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 を指定できるようになりました。

    • 例えば、 queryflags オプションを vector を使って以下のように記述できます。

      select \
        --table Memos \
        --filter 'query("content", "-content:@mroonga", \
                        { \
                          "expander": "QueryExpanderTSV", \
                          "flags": ["ALLOW_LEADING_NOT", "ALLOW_COLUMN"] \
                        })'
      
  • [select] 動的カラムに新しいステージ result_set を追加しました。

    • このステージは、結果セットのテーブルにカラムを作ります。したがって、 queryfilter が存在しない場合は作られません。

      • queryfilter が存在しない場合は、結果セットのテーブルが作られないためです。

    • このステージでは _value は使用できません。 result_set ステージの値は score_column に格納されます。

  • [vector_slice] 重み付きベクターの重みに Float32 型が使えるようになりました。 [GitHub#1106 naoaさんがパッチ提供]

  • [select] drilldownsの動的カラムのステージに filteredoutput を追加しました。 [GitHub#1101 naoaさんがパッチ提供][GitHub#1100 naoaさんがパッチ提供]

    • drilldowns[Label].stage filtereddrilldowns[Label].stage output のように drilldowns の動的カラムのステージに filteredoutput を使えます。

  • [select] ドリルダウンでの集計に Float 型の値をサポートしました。

    • MAXMINSUM を使って 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_idGRN_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_floatfloat として値を返します。

      • 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_tftf とは、単語の出現頻度です。

      • 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の後に出力されます。

    • 現在、この機能をサポートしているのは、 dumplogical_range_filter のみです。

    • logical_range_filter は、 command_version 3 以降では、常に出力がstreamとして返ります。

    • この機能は以下の制限があります。

      • limit に指定できる負の値は -1 のみです。

      • MessagePack形式の出力はサポートしていません。

    • この変更で、JSONの応答内容を少し変更しています。

      • 以下のように以前のバージョンとは、キーの順序が異なっています。

        • 以前のバージョンのキーの順序

          {
            "header": {...},
            "body": {...}
          }
          
        • 本バージョン(10.0.0)のキーの順序

          {
            "body": {...},
            "header": {...}
          }
          
    • dumplogical_range_filtercommand_version 3 で実行した時はキャッシュが効きません。

      • 10.0.0から dumplogical_range_filtercommand_version 3 の時にストリームで応答を返すので、応答全体をキャッシュできないためです。

  • [logical_range_filter] Apache Arrow形式での応答をサポートしました。

    • 以下のデータ型をサポートしています。

      • UInt8

      • Int8

      • UInt16

      • Int16

      • UInt32

      • Int32

      • UInt64

      • Int64

      • Time

      • ShortText

      • Text

      • LongText

      • Vector of Int32

      • Reference vector

  • Ubuntu 20.04 (Focal Fossa)をサポートしました。

  • Ubuntu 19.04 (Disco Dingo)のサポートをやめました。

    • このバージョンはEOLになっているためです。

9.1.2リリース - 2020-01-29#

改良#

  • [tools] 指定したテーブルまたはカラムのファイルのみをコピーするスクリプトを追加しました。

    • このスクリプトの名前は、copy-related-files.rbです。

    • このスクリプトは非常に大きいデータベースから指定したテーブルまたはカラムを抽出したい場合に便利です。

    • 特定のテーブルまたはカラムに関連するファイルは、障害の再現に必要なことがあります。

    • データベースをまるごと提供するのが難しい場合は、このツールを使って対象のテーブルまたはカラムに関連するファイルを抽出できます。

  • [shutdown] 全てのスレッドが使われている場合でも、 /d/shutdown?mode=immediate を即時受け付けるようにしました。

    • この機能はGroonga HTTPサーバでのみ使えます。

  • GRN_ENABLE_REFERENCE_COUNT=yes を使うと、使用していないオブジェクトをすぐに開放します。

    • この機能は実験的です。パフォーマンスが低下します。

    • 多くのテーブルにまたがるデータをロードする際等にメモリーの使用量を一定量に保つ効果が期待できます。

  • [CentOS] groonga-release パッケージをバージョンごとに用意しました。

    • インストール方法に少し変更があるので注意してください。

  • [Debian GNU/Linux] Groongaのaptリポジトリーの追加に groonga-archive-keyring を使うようにしました。

    • この改善によって、Groongaのaptリポジトリーを簡単に追加できます。

    • groonga-archive-keyring はGroongaのaptリポジトリーを使うための全ての情報が入っています。そのため、リポジトリー情報やPGPキーの変更を意識する必要がありません。

    • groonga-archive-keyring はdebパッケージなので、 apt update で簡単に更新できます。

9.1.1リリース - 2020-01-07#

改良#

  • [load] Apache Arrow 形式のデータをサポートしました。

    • Apache Arrow形式のデータを使うことで、パースのコストを削減でき、他のフォーマットより高速にデータをロードできる可能性があります。

    • この変更によって、他のデータ分析システムからApache Arrow形式のデータを直接Groongaへ入力することもできます。

    • Apache Arrow形式のフォーマットはHTTPインターフェイスでのみ使えます。コマンドラインインターフェイスでは使えません。

  • [load] Apache Arrow 形式のロード方法をドキュメントに追加しました。

  • [load] エラーメッセージを改善しました。

    • load コマンドのレスポンスにエラーメッセージも含むようにしました。

    • この変更によって、データのロードに失敗した場合、 load コマンドのエラーの詳細を出力します。

  • [httpd] バンドルしているnginxのバージョンを1.17.7に更新しました。

  • [Groonga HTTPサーバー] HTTPリクエストのbodyにコマンドのパラメータを指定できるようにしました。

    • この場合、 Content-Typeapplication/x-www-form-urlencoded を指定しなければいけません。

  • [Groonga HTTPサーバー] HTTP POST の使用方法をドキュメントに追加しました。

9.1.0リリース - 2019-11-29#

改良#

  • "&&"演算のパフォーマンスを改善しました。

    • 例えば、以下のような条件式のパフォーマンスが向上します。

    • ( A || B ) && ( C || D ) && ( E || F) ...

  • [TokenMecab] TokenMecabuse_base_form オプションを追加しました。

    • このオプションによってトークンの原型を使って検索できます。

    • 例えば、このオプションを使って"支えた"を検索した場合、"支える"もヒットします。

修正#

  • インデックスがアクセサーの際にパフォーマンスが低下する問題を修正しました。

    • 例えば、以下のような条件を含むクエリーで起こります。

      • accessor @ query

      • accessor == query

  • バッファーが十分に大きい時に、検索結果の推定サイズがオーバーフローする問題を修正しました。 [PGroonga#GitHub#115][Albert Songさんの報告]

  • test(1)のポータビリティを改善しました。(おばたさんがパッチ提供)

  • 不足しているツールを追加

    • 前のバージョンに index-column-diff-all.shobject-inspect-all.sh がバンドルされていなかったためです。

感謝#

  • Albert Songさん

  • おばたさん

9.0.9リリース - 2019-10-30#

注釈

今回のバージョンからパフォーマンスが低下しているかもしれません。もし、以前よりパフォーマンスが低下していたら、是非、再現手順を報告してほしいです。

改良#

  • [ログ] 応答の送信時間をクエリーログに出力するように改良しました。

  • [status] status コマンドの応答に現在のジョブ数を追加しました。

  • [groonga-httpd] $request_time をサポートしました。

    • 以前のバージョンでは、 log_format ディレクティブに $request_time を指定しても、$request_time の値は常に0でした。

    • 今回のバージョンから、 $request_time を指定した場合、 groonga-httpd は正しい時間を出力します。

  • [groonga-httpd] $request_time の設定方法をドキュメントに追加しました。

  • Ubuntu 19.10(Eoan Ermine)をサポートしました。

  • CentOS 8をサポートしました。(実験的)

    • CentOS 8向けのパッケージは開発用のパッケージが不足しているため、一部の機能が使えません。(例えば、 TokenMecab が使えなかったり、JSON文字列からint32のベクターへのキャストが出来なかったりします。)

  • [tools] index_column_diff コマンドを簡単に実行するスクリプトを追加しました。

    • このスクリプトの名前は、index-column-diff-all.shです。

    • このスクリプトは、Groongaのデータベースからインデックスカラムを抽出し、抽出したインデックスカラムに対して index_column_diff を実行します。

  • [tools] object_inspect コマンドを全てのオブジェクトに対して実行するスクリプトを追加しました。

    • このスクリプトの名前は、object-inspect-all.shです。

修正#

  • between の最初の引数として値を指定すると、Groongaがクラッシュする問題を修正しました。[GitHub#1045][yagisumiさんの報告]

感謝#

  • yagisumiさん

9.0.8リリース - 2019-09-27#

改良#

  • [log_reopen] 2つ以上のワーカーで groonga-httpd を使用する場合の補足説明を追記しました。

  • 作成中のインデックスを無視するように改良しました。

    • インデックス構築中であっても、正しい検索結果を取得できます。

    • ただし、この場合、Groongaは検索にインデックスを使用しないため、検索は遅くなります。

  • [sub_filter] 対象のカラムのインデックスが作成中か、または、インデックスが無い時に sub_filter がシーケンシャルサーチを実行する機能を追加しました。

    • 以前のバージョンでは、上記の状態の場合、 sub_filter はエラーになりました。

    • 今回のバージョンから、 上記の状態でも sub_filter は検索結果を返します。

    • ただし、上記の状態の場合、 sub_filter は、シーケンシャルサーチで実行されるため遅いです。

  • [CentOS] CentOS 6の32-bitパッケージのサポートをやめました。

修正#

  • [logical_range_filter] レコードが十分にあるとき、かつフィルター条件にマッチしないレコードが推定値を超えた時に、同じオブジェクトを2回閉じるという例外が発生する問題を修正しました。

9.0.7リリース - 2019-08-29#

改良#

  • [httpd] バンドルしているnginxのバージョンを1.17.3に更新しました。

    • CVE-2019-9511、CVE-2019-9513、CVE-2019-9516のセキュリティの修正が含まれています。

修正#

  • ポスティングリストが巨大になった時にGroongaがクラッシュする問題を修正しました。

    • ただし、このバグは、一般的なデータでは殆ど発生しません。ポスティングリストは、一般的なデータでは、そこまで大きくならないためです。

  • 動的カラムのステージに initial を指定し、インデックスを使用した検索をすると空の結果を返す問題を修正しました。 [GitHub#683]

  • configure時にlibeditがインストールされているにもかかわらず、検知しない問題を修正しました。 [GitHub#1030][yuさんがパッチ提供]

  • --slices--sort_keys オプション使用時に --offset--limit オプションが動作しない問題を修正しました。 [clear-code/redmine_full_text_search#70][a9zawaさんの報告]

  • select コマンドの結果が巨大な時、検索結果が空になる問題を修正しました。[groonga-dev,04770][Yutaro Shimamuraさんの報告]

  • 前方一致検索や後方一致検索時に適切なインデックスを使わない問題を修正しました。[GitHub#1007, PGroonga#GitHub#96][oknjさんの報告]

感謝#

  • oknjさん

  • Yutaro Shimamuraさん

  • yuさん

  • a9zawaさん

9.0.6リリース - 2019-08-05#

改良#

  • Debian 10 (buster)をサポートしました。

修正#

  • [select] 検索エスカレーションが起こった際に検索がエラーになるバグを修正しました。

  • [select] ネストされた等価演算を使った際に、誤った検索結果を返すことがあるバグを修正しました。

  • [geo_distance_location_rectangle] load のフォーマットが誤っている例を修正しました。 [GitHub#1023] [yagisumiさんがパッチ提供]

  • [マイクロブログ検索システムの作成] 検索結果が誤っている例を修正しました。[GitHub#1024][yagisumiさんがパッチ提供]

感謝#

  • yagisumiさん

9.0.5リリース - 2019-07-30#

警告

このリリースには影響の大きい不具合があることがわかりました。select コマンドが誤った結果を返します。この問題を修正し、9.0.6をリリースする予定です。Groonga 9.0.5は使わず、後日リリースされる9.0.6を使ってください。問題の詳細については https://groonga.org/ja/blog/2019/07/30/groonga-9.0.5.html で解説しています。

改良#

  • [logical_range_filter] 検索対象のシャードが十分に大きい時にのみ最適化を適用するように改良しました。

    • この機能は、ソートキーが同じ時にオフセット間で検索結果が重複するのを減らします。

    • 十分に大きいのしきい値はデフォルトで10000レコードです。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション unify_to_katakana を追加しました。

    • このオプションは、平仮名を片仮名にノーマライズします。

    • 例えば、 ゔぁゔぃゔゔぇゔぉヴァヴィヴヴェヴォ にノーマライズします。

  • [select] slicesパラメーターでdrilldownsをサポートしました。

  • [select] slicesパラメーターでcolumnsをサポートしました。

  • [select] initialステージ内でslicesパラメーターが _score を参照できるよう改良しました。

  • [highlight_html], [snippet_html] slicesパラメータ指定時に、slices実行前の式からもキーワードを抽出するように改良しました。

  • slicesパラメータ指定時に、slices実行前の式からもスコアーを収集するように改良しました。

  • ポスティングリストにポスティングを追加する際に自動的にスコアーを1増やすのをやめました。

    • grn_ii_posting_add は、この変更によって後方互換性がなくなりました。互換性を保つには、呼び出し側でスコアーを増やす必要があります。

  • XXX.YYY.ZZZ == AAA のようなネストされた等価演算のインデックス検索をサポートしました。

  • ハッシュテーブル使用時にハッシュの再構築の間隔を少なくしました。

    • この昨日によって、結果出力のパフォーマンスが改善します。

  • クエリーログにプレフィックスを追加できるようになりました。

    • どの条件のフィルターなのかわかりやすくなります。

  • Apache Arrow 1.0.0 をサポートしました。

    • ただし、このバージョンはまだ、リリースされていません。

  • Amazon Linux 2 をサポートしました。

修正#

  • "[1, 2, 3]" のようなJSONのベクター値がインデックスされないバグを修正しました。

  • table_create のテストのパラメーター名が誤っていたバグを修正しました。[GitHub#1000][yagisumiさんがパッチ提供]

  • command_version=3 でdrilldownコマンドが実行された際に、ドリルダウンのラベルが空になるバグを修正しました。[GitHub#1001][yagisumiさんの報告]

  • MinGWでWindows版のパッケージのビルドが失敗するバグを修正しました。

  • MinGWのWindows版パッケージにCOPYINGがインストールされないバグを修正しました。

  • ハイライト対象として、クエリーにテキスト以外を指定した際に、キーワードがハイライトされないバグを修正しました。

  • [object_inspect] のMessagePack形式の出力が壊れるバグを修正しました。[GitHub#1009][yagisumiさんの報告]

  • index_column_diff のMessagePack形式の出力が壊れるバグを修正しました。[GitHub#1009][yagisumiさんの報告]

  • [suggest] のMessagePack形式の出力が壊れるバグを修正しました。[GitHub#1011][yagisumiさんの報告]

  • パトリシアトライのテーブルの検索時などにreallocのサイズが十分に確保されないバグを修正しました。[島津製作所さんの報告]

    • Groongaはこのバグでクラッシュする可能性があります。

  • groonga-release version 1.5.0より前から1.5.0-1へアップデートした際に groonga.repo が削除されるバグを修正しました。[groonga-talk:429][Josep Sanzさんの報告]

感謝#

  • yagisumiさん

  • 島津製作所さん

  • Josep Sanzさん

9.0.4リリース - 2019-06-29#

改良#

  • 配列リテラルの複数要素をサポートしました。

  • ベクターの等価演算をサポートしました。

  • [logical_range_filter] 出力するクエリーログを追加しました。

    • logical_range_filter コマンドが、以下のタイミングでログを出力するようになります。

      • logical_range_filter によるフィルター後

      • logical_range_filter によるソート後

      • 動的カラム適用後

      • 結果出力後

    • この機能によって、このコマンドがどこまで完了したかを見ることができます。

  • [トークナイザー] TokenPattern の説明をドキュメントに追加しました。

  • [トークナイザー] TokenTable の説明をドキュメントに追加しました。

  • [トークナイザー] TokenNgram の説明をドキュメントに追加しました。

  • [grndb] groonga.logへの操作ログの出力を追加しました。

    • grndb コマンドが実行結果と実行過程を出力するようになります。

  • [grndb] 空のファイルのチェックをサポートしました。

    • この機能によって、空のファイルが存在するかどうかをチェックできます。

  • [grndb] 新しいオプション --since を追加しました。

    • 検査の範囲を指定できます。

  • [grndb] 新しいオプション --since についてのドキュメントを追加しました。

  • RapidJSONをバンドルしました。

    • 部分的にGroongaのJSONパーサーとしてRapidJSONを使うことができます。(この機能はまだ部分的です。)

    • これを使うことでより厳格なJSONのパースができます。

  • JSON文字列からint32のベクターへのキャストをサポートしました。

    • この機能は、RapidJSONが必要です。

  • [query] default_operator を追加しました。

    • "keyword1 keyword2"時の演算子をカスタマイズできます。

    • デフォルトでは、"keyword1 keyword2"はAND演算です。

    • "keyword1 keyword2"の演算子をAND以外に変更できます。

修正#

  • [optimizer] 複数のfilter条件と xxx.yyy=="keyword" のような条件を指定した際にエラーが発生するバグを修正しました。

  • GroongaのWindows用のパッケージ(VC++版)に不足していたライセンスファイルを追加しました。

  • GroongaのWindows用のパッケージ(VC++版)UCRTランタイムを追加しました。

  • [ウィンドウ関数] メモリリークを修正しました。

    • これは、複数のウインドウに対してソートキーを適用した際に発生します。 [Takashi Hashidaさんがパッチ提供]

感謝#

  • Takashi Hashidaさん

9.0.3リリース - 2019-05-29#

改良#

  • [select] より多くのクエリーログを追加しました。

    • select コマンドが、以下のタイミングでログを出力するようになります。

      • ドリルダウンによるソート後

      • ドリルダウンによるフィルター後

    • この機能によって、このコマンドがどこまで完了したかを見ることができます。

  • [logical_select] より多くのクエリーログを追加しました。

    • logical_select コマンドが、以下のタイミングでログを出力するようになります。

      • 動的カラム作成後

      • ドリルダウンによるグループ化後

      • ドリルダウンによるソート後

      • ドリルダウンによるフィルター後

      • logical_select によるソート後

    • この機能によって、このコマンドがどこまで完了したかを見ることができます。

  • [logical_select] limit オプションを使用したときのソートのパフォーマンスを少し改善しました。

  • [index_column_diff] パフォーマンスを改善しました。

    • このコマンドの実行速度を大幅に短くしました。

  • [index_column_diff] 無効な参照を無視するように改良しました。

  • [index_column_diff] ベクター要素の重複に対応しました。

  • [Normalizers] Unicode 12.1 の NFKC(Normalization Form Compatibility Composition)をベースにしたノーマライザー NormalizerNFKC121 を追加しました。

  • [TokenFilters] Unicode 12.1 の NFKC(Normalization Form Compatibility Composition)をベースにしたトークンフィルター NormalizerNFKC121 を追加しました。

  • [grndb] 新しいオプション --log-flags を追加しました。

    • groonga実行ファイルと同様、ログに出力する項目を指定できます。

    • サポートされているログフラグについては、[groonga 実行ファイル] を参照してください。

  • [snippet_html] 検索にマッチしない時の戻り値を変更する新しいオプションを追加しました。

  • [plugin_unregister] Windowsのフルパスをサポートしました。

  • 複数行のログメッセージをサポートしました。

    • この機能によって、複数行に渡るログメッセージが見やすくなります。

  • インデックスを使って検索した際、キーをGroongaのログに出力するようにしました。

  • [match_columnsパラメータ] インデックスの重みのドキュメントを追加しました。

  • [logical_range_filter] order パラメータの説明を追加しました。

  • [object_inspect] 新しい統計 INDEX_COLUMN_VALUE_STATISTICS_NEXT_PHYSICAL_SEGMENT_IDINDEX_COLUMN_VALUE_STATISTICS_N_PHYSICAL_SEGMENTS の説明を追加しました。

  • Ubuntu 14.04 のサポートをやめました。

修正#

  • [index_column_diff] remains を多く報告するバグを修正しました。

  • --without-onigmo オプションを使った際にビルドエラーになるバグを修正しました。[GitHub#951] [Tomohiro KATOさんが報告]

  • "CVE: 2019-11675"の脆弱性を修正しました。[Wolfgang Hotwagnerさんが報告]

  • Windows版のGroongaにて、拡張パスプレフィックス \\?\ を削除しました。[GitHub#958] [yagisumiさんが報告]

    • この拡張プレフィックスは、プラグインを正確に見つけられないというバグを引き起こします。

感謝#

  • Tomohiro KATOさん

  • Wolfgang Hotwagnerさん

  • yagisumiさん

9.0.2リリース - 2019-04-29#

このリリースからVC++で作成したWindows版パッケージを提供します。

今までどおり、MinGWで作成したWindows版パッケージも提供しますが、近いうちにMinGWで作ったパッケージの代わりにVC++で作ったパッケージを提供する予定です。

改良#

  • [column_create] 新しいフラグ INDEX_LARGE を追加しました。

    • このフラグによって、デフォルトの2倍の領域を持つインデックスカラムを作成できます。

    • ただ、メモリ使用量も2倍となることに注意して下さい。

    • このフラグは、インデックス対象のデータが大きい時に有用です。

    • 大きいデータとは、大量のレコード(通常は少なくとも1000万レコード以上)があり、少なくとも次のうちの1つ以上の特徴があります。

      • インデックス対象が複数のカラム

      • インデックステーブルにトークナイザーが付いている

  • [object_inspect] セグメントの新しい統計値 next_physical_segment_idmax_n_physical_segments を追加しました。

    • この情報で、インデックスカラムの領域の使用量とインデックスカラムの領域の最大値を確認できます。

  • [logical_select] シャードをまたがったウィンドウ関数をサポートしました。

  • [logical_range_filter] シャードをまたがったウインドウ関数をサポートしました。

  • [logical_count] シャードをまたがったウインドウ関数をサポートしました。

  • このリリースからVC++で作成したWindows版パッケージを提供するようにしました。

  • [io_flush] 新しいオプション --recursive dependent を追加しました。

    • 指定した書き出し対象オブジェクトとその子オブジェクトすべて、参照先のテーブル、インデックスが張られているカラムがある場合、対応するインデックスカラムとそのインデックスカラムのテーブルを書き出し対象オブジェクトにできます。

修正#

  • 一部の環境でコンパイルエラー "unknown type name 'bool'" が発生する問題を修正しました。

  • mrubyを経由して実行するコマンド(例えば、 logical_selectlogical_range_filterlogical_count 等)で、Int32を超える数を正しく出力できない問題を修正しました。[GitHub#936] [HashidaTKSさんがパッチ提供]

感謝#

  • HashidaTKSさん

9.0.1リリース - 2019-03-29#

改良#

  • ベクターの値にnullが使えるようになりました。

    • select ... --columns[vector].flags COLUMN_VECTOR --columns[vector].value "null" のように使用できます。

  • [dump] ドキュメントを英語に翻訳しました。

  • 無効なインデックスのチェックとログへの記録を強化しました。インデックス関連のバグを発見するのに役立ちます。

  • 8.0.6リリース - 2018-08-29GRN_TABLE_SELECT_ENOUGH_FILTERED_RATIO の説明を改善しました。

  • [select] 新しい引数 --load_table--load_columns--load_values を追加しました。

    • select の結果を --load_table で指定したテーブルへ格納できます。

    • --load_values オプションは、select の結果のカラムを指定します。

    • --load_columns オプションは、--load_table で指定したテーブルのカラムを指定します。

    • このようにして、--load_values で指定したカラムの値を、 --load_columns で指定したカラムへ格納できます。

  • [select] 新しい引数 --load_table--load_columns--load_values を追加しました。

  • [load] ロード先のテーブルをクエリーログに表示するようにしました。

    • 以下のように、ロード先のテーブル名は [] 内の文字列として表示します 。

    • :000000000000000 load(3): [LoadedLogs][3]

  • 以下のAPIを追加しました。

    • grn_ii_get_flags()

    • grn_index_column_diff()

    • grn_memory_get_usage()

  • 壊れたインデックスをチェックするためのコマンド index_column_diff を追加しました。コマンド実行の進捗を記録したい場合は、ログレベルをdebugに設定してください。

修正#

  • [snippet_html] 一致しない場合、空のベクターを返すよう変更しました。

    • そのような場合、 null の代わりに空のベクター [] が返されます。

  • スレッドカウントがオーバフローする可能性についての警告を修正しました。実運用では、膨大な数のスレッドが使用されていないため、ユーザーに影響はありません。[GitHub#904]

  • maxOSでのビルドエラーを修正しました。 [GitHub#909] [shiro615さんが報告]

  • ストップワードの処理のバグを修正しました。

    • このバグは、クエリーの最初のトークンをストップワードとして設定すると発生します。

    • このバグが発生した場合、検索クエリーはヒットしません。

  • [全体設定] grn_lock_set_timeout のパラメーター名の誤字を修正しました。

  • インデックスの破損によって、削除されたレコードがマッチするバグを修正しました。

    • 大量のレコードを追加または、削除した時に発生することがあります。

  • logical_range_filter がレコードを返さない場合のメモリリークを修正しました。[GitHub#911] [HashidaTKSさんがパッチ提供]

  • ロードしているデータが正しくノーマライズされないことによってクエリーにマッチしないバグを修正しました。[PGroonga#GitHub#93, GitHub#912,GitHub#913] [kamicupさんとdodaisukeさんが報告]

    • このバグは、カタカナの後ろに空白のあるデータをロードし、ノーマライザーに unify_kana オプションが使用された時に発生します。

  • インデックスの更新中にインデックスが破損するバグを修正しました。

    • 長期間、大量のレコードの追加、削除を繰り返した時に発生することがあります。

  • インデックス更新時に十分な作業領域を確保できずにクラッシュするバクを修正しました。

感謝#

  • shiro615さん

  • HashidaTKSさん

  • kamicupさん

  • dodaisukeさん

9.0.0リリース - 2019-02-09#

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

改良#

  • [トークナイザー] 新しいトークナイザー TokenPattern を追加しました。

    • 正規表現を使ってトークンを抽出できます。

      • このトークナイザーは正規表現にマッチしたトークンのみを抽出します。

    • 正規表現のパターンは複数指定できます。

  • [トークナイザー] 新しいトークナイザー TokenTable を追加しました。

    • 既存のテーブルのカラムの値を使ってトークンを抽出できます。

  • [dump] バイナリデータのダンプに対応しました。

  • [select] インデックスカラムに対する類似文書検索をサポートしました。

    • マルチカラムインデックスを使用している場合、この機能を使って、全てのソースカラムに対して類似文書検索ができます。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション remove_blank を追加しました。

    • このオプションは空白を取り除きます。

  • [groonga 実行ファイル] ログ内のThreadIDの表示を改善しました。

    • Windows版では、ProcessIDとThreadIDを混同しやすかったので、どちらがThreadIDでどちらがProcessIDかを明確にしました。

8.1.1リリース - 2019-01-29#

改良#

  • [logical_select] 新しい引数 --load_table--load_columns--load_values を追加しました。

    • logical_select の結果を --load_table で指定したテーブルへ格納できます。

    • --load_values オプションは、logical_select の結果のカラムを指定します。

    • --load_columns オプションは、--load_table で指定したテーブルのカラムを指定します。

    • このようにして、--load_values で指定したカラムの値を、 --load_columns で指定したカラムへ格納できます。

  • インデックスの更新エラー時のログを改善しました。

    • ログに、より詳細な情報を追加しました。

      • 例えば、ポスティングリストのマージに失敗した時にマージ元のバッファーとチャンクを出力します。

      • また、バッファー確保のエラーが発生した時は、バッファーの空き領域と要求サイズをログに出力します。

  • [groonga 実行ファイル] 新しいオプション --log-flags を追加しました。

    • Groongaのログに出力する項目を指定できます。

    • 以下のような項目を出力できます。

      • タイムスタンプ

      • ログメッセージ

      • ロケーション(ログが出力された場所)

      • プロセスID

      • スレッドID

    • 以下のように接頭辞を指定できます。

      • +

        • この接頭辞は、 "フラグを追加する"という意味です。

      • -

        • この接頭辞は、"フラグを削除する"という意味です。

      • 接頭辞無しは、"存在しているフラグを置き換える"という意味です。

    • 具体的には、以下のようにフラグ指定できます。

      • none

        • ログに何も出力しません。

      • time

        • ログにタイムスタンプを出力します。

      • message

        • ログにメッセージを出力します。

      • location

        • ログの出力場所(ファイル名、行数、関数名)とプロセスIDを出力します。

      • process_id

        • ログにプロセスIDを出力します。

      • pid

        • このフラグは、 process_id のエイリアスです。

      • thread_id

        • ログにスレッドIDを出力します。

      • all

        • このフラグは、 nonedefault 以外の全てのフラグを指定します。

      • default

        • ログに、タイムスタンプとログメッセージを出力します。

    • | を使って、複数のフラグを指定することもできます。

修正#

  • インデックスの更新エラー発生時にメモリリークする問題を修正しました。

  • [ノーマライザー] ステートレスなノーマライザーとステートフルなノーマライザーを同時に使用した時に、それらが誤った結果を返すバグを修正しました。

    • ステートレスなノーマライザーとは以下です。

      • unify_kana

      • unify_kana_case

      • unify_kana_voiced_sound_mark

      • unify_hyphen

      • unify_prolonged_sound_mark

      • unify_hyphen_and_prolonged_sound_mark

      • unify_middle_dot

    • ステートフルなノーマライザーとは以下です。

      • unify_katakana_v_sounds

      • unify_katakana_bu_sound

      • unify_to_romaji

8.1.0リリース - 2018-12-29#

改良#

  • [httpd] バンドルしているnginxのバージョンを1.15.8に更新しました。

修正#

  • io_flush コマンド実行後に、DBに対するアンロックが常にフラッシュの実行後になってしまうバグを修正しました。

  • 参照先を持たないレコードを持つテーブルに対して reindex コマンドを実行した際に、 reindex コマンドが終了しないバグを修正しました。

8.0.9リリース - 2018-11-29#

改良#

  • [トークナイザー] トークナイザーの作成に失敗した際のエラーメッセージにトークナイザーの名前を出力するよう改良。

  • [トークナイザー][TokenDelimit] トークンの区切り文字のカスタマイズをサポートしました。

    • 空白以外のトークンを区切り文字に使えます。

  • [トークナイザー][TokenDelimit] 新しいオプション pattern を追加しました。

    • このオプションにより、区切り文字にに正規表現を指定できます。

  • [トークナイザー] 各トークンの情報に force_prefix_search の値を追加しました。

    • "force_prefix" は後方互換のため残しています。

  • [トークンフィルター] ビルトインのトークンフィルタ TokenFilterNFKC100 を追加しました。

    • NormalizerNFKC100のように unify_kana オプションで、カタカナをひらがなへ変換できます。

  • [トークンフィルター][TokenFilterStem] 新しオプション algorithm を追加しました。

    • このオプションによって、英語以外の言語(フランス語、スペイン語、ポルトガル語、イタリア語、ルーマニア語、ドイツ語、オランダ語、スウェーデン語、ノルウェー語、デンマーク語、ロシア語、フィンランド語)をステミングできます。

  • [トークンフィルター][TokenFilterStopWord] 新しいオプション column を追加しました

    • このオプションによって、is_stop_word以外のカラムをスットプワードに指定できます。

  • [dump] トークンフィルターのオプションの出力をサポートしました。

    • TokenNgramTokenMecab 等のようなオプションを持つトークナイザーを指定した場合、それらのオプションも table_list コマンドで出力できます。

  • [truncate] トークンフィルターのオプションを持ったテーブルをサポートしました。

    • TokenFilterStemTokenStopWord 等のようなオプションを持つトークナイザーを持つテーブルでも truncate できます。

  • [schema] トークンフィルターのオプションの出力をサポートしました。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション unify_to_romaji を追加しました。

    • このオプションによって、ひらがなとカタカナをローマ字に正規化できます。

  • [query-log][show-condition] "func() > 0"をサポートしました。

  • [Windows] アンマップ前のフラッシュを確実にするよう改善しました。

  • ファイル入力のエラーメッセージを改善しました。

  • [httpd] バンドルしているnginxのバージョンを1.15.7に更新しました。

    • CVE-2018-16843とCVE-2018-16844のセキュリティの修正が含まれています。

修正#

  • ウインドウ関数を評価する際にメモリリークする問題を修正しました。

  • [groonga-httpd] ログの内容が混在することがあるバグを修正しました。

  • output_columnsのスライスのエラーが発生した際に、無効なJSONが生成されるバグを修正しました。

  • ネストして参照されているベクターカラムの値を取得する際にメモリリークする問題を修正しました。

  • インデックス破損を警告するログを出力する際にクラッシュするバグを修正しました。

  • 式の評価で一時的なベクターが再利用された時にクラッシュするバグを修正しました。

    • 例えば、以下のようにベクターを使った式を評価する時にクラッシュします。

    _score = _score + (vector_size(categories) > 0)

  • deleteコマンドで削除したベクターカラムの値がヒットするバグを修正しました。[dodaisukeさんの報告]

感謝#

  • dodaisukeさん

8.0.8リリース - 2018-10-29#

改良#

  • [table_list] デフォルトトークナイザーのオプションをサポートしました。

    • TokenNgramTokenMecab 等のようなオプションを持つトークナイザーを指定した場合、それらのオプションも table_list コマンドで出力できます。

  • [select] record @ 'query' を使ったシーケンシャルマッチでノーマライザーのオプションをサポートしました。

  • [truncate] トークナイザーのオプションを持ったテーブルをサポートしました。

    • TokenNgramTokenMecab 等のようなオプションを持つトークナイザーを持つテーブルでも truncate できます。

  • [トークナイザー][TokenMecab] TokenMecabtarget_class オプションを追加しました。

    • このオプションは、指定した品詞のトークンを検索します。例えば、名詞のみを検索することができます。

    • このオプションは、以下のようにサブクラスを指定することや、 +- を使って、特定の品詞を追加または除外することもできます。したがって、以下のように代名詞を除外して検索することもできます。

      'TokenMecab("target_class", "-名詞/代名詞", "target_class", "+")'

  • [io_flush] io_flush 中のデータベースのロックをサポートしました。

    • io_flush 実行中に io_flush 対象のテーブルを削除するとGroongaがクラッシュする問題があったためです。

  • [cast_loose] 新しい関数 cast_loose() を追加しました。

    • この関数は、指定した型へキャストします。もし、指定した値がキャストできない場合、値は、指定したデフォルト値になります。

  • 条件式の評価順序の最適化を追加しました。(実験的)

    • 以下のように環境変数を設定することでこの機能を有効にできます。

      GRN_EXPR_OPTIMIZE=yes

  • インデックス検索可能な正規表現に (?-mix:XXX) 記法をサポートしました。 [groonga-dev,04683][ Masatoshi SEKIさんの報告]

    • (?-mix:XXX) は XXX と同じ扱いです。

  • [httpd] バンドルしているnginxのバージョンを1.15.5に更新しました。

  • Ubuntu 18.10 (Cosmic Cuttlefish)をサポートしました。

修正#

  • Groonga GQTP サーバーが新しい接続を受け付けなくなることがあるバグを修正しました。[groonga-dev,04688][Yutaro Shimamuraさんの報告]

    • quitを使わずにクライアントプロセスを中断した時に発生します。

感謝#

  • Masatoshi SEKIさん

  • Yutaro Shimamuraさん

8.0.7リリース - 2018-09-29#

改良#

  • [トークナイザー][TokenMecab] Mecabのメタデータの出力をサポートしました。

    • TokenMecabinclude_class オプションを追加しました。

      このオプションは、Mecabのメタデータの classsubclass を出力します。

    • TokenMecabinclude_reading オプションを追加しました。

      このオプションは、Mecabのメタデータの reading を出力します。

    • TokenMecabinclude_form オプションを追加しました。

      このオプションは、Mecabのメタデータの inflected_typeinflected_formbase_form を出力します。

    • TokenMecabuse_reading オプションを追加しました。

      このオプションは、読みがなによる検索をサポートします。

      このオプションは、読みがなを使った検索をするため、表記ゆれの対策として有用です。

  • [plugin] 複数のディレクトリからプラグインを取得できるようになりました。

    GRN_PLUGINS_PATH に複数のディレクトリを指定できます。Windowsの場合は、":"でWindows以外では、";"で区切ります。

    GRN_PLUGINS_PATH は、 GRN_PLUGINS_DIR より優先度が高いです。現状、このオプションはWindowsではサポートされていません。

  • [トークナイザー][TokenNgram] TokenNgramunify_alphabet オプションを追加しました。

    unify_alphabetfalse として使うと、 TokenNgram はASCII文字のトークナイズ方法にバイグラムを使います。

  • [トークナイザー][TokenNgram] TokenNgramunify_symbol オプションを追加しました。

    TokenNgram("unify_symbol", false) は、 TokenBigramSplitSymbol と同じ動作です。

  • [トークナイザー][TokenNgram] TokenNgramunify_digit オプションを追加しました。

    unify_digitfalse として使うと、 TokenNgram は数字のトークナイズ方法にバイグラムを使います。

  • [httpd] バンドルしているnginxのバージョンを1.15.4に更新しました。

修正#

  • いくつかのケースでの誤ったスコア計算を修正しました。

    • ブール値に数値を加算、乗算または除算するときに発生します。

    • !=== を使ってスカラーとベクトルの列を比較するときに発生します。

8.0.6リリース - 2018-08-29#

改良#

  • [トークナイザー][TokenMecab] chunked_tokenizechunk_size_threshold の両オプションに対応しました。

  • [optimizer] query family expressionの推定に対応しました。column @ querycolumn @~ pattern のようなquery family expressionについて、より効果的な実行計画を立てられます。

  • [optimizer] オプティマイザをプラグインから組み込みの機能に変更し、初期状態で無効としました。環境変数を GRN_EXPR_OPTIMIZE=yes と定義するか、従来通りに expression_rewriters テーブルを使う事で機能を有効化できます。

  • 充分に絞り込み済みの場合において、初期状態でシーケンシャルサーチを行うようにしました。現在の結果が充分に少数である場合、シーケンシャルサーチはインデックス検索よりも高速です。現在の結果がテーブル内の全レコードの1%で1000件未満の場合、インデックス検索可能な場合であってもシーケンシャルサーチが使われます。

    現在、この最適化は、 ==><>=<= を使った検索時に適用されます。

    絞り込みに指定したカラムを持つテーブルのキーが ShortText の場合、この最適化を適用するためには、そのテーブルのノーマライザーを NormalizerAuto にする必要があります。

    この機能は環境変数で GRN_TABLE_SELECT_ENOUGH_FILTERED_RATIO=0.0 と設定する事で無効化できます。

  • [load] エラーメッセージにテーブル名を含めるようにしました。

  • [load] lock_table オプションを追加しました。--lock_table yes が指定された場合、カラムの更新と --each の適用を行っている間、load は対象のテーブルをロックします。このオプションは loaddelete の衝突を防ぎますが、読み込みの性能を低下させるでしょう。

  • [vector_find] サポートされていないモードでクラッシュしないようにしました。

修正#

  • [index] HASH_KEY を伴ったテキストのベクターに対するオフラインでのインデックス構築に関して、誤ったセクションIDを持つインデックスが構築されてしまうバグを修正しました。

  • --match_columns 'index[0] || index[9]' が誤ったセクションを使用してしまう問題を修正しました。

  • [highlighter] 語彙表がハッシュテーブルで、且つキーワードがN-gramのNよりも少ない文字数の場合に、誤ったハイライトが行われていた問題を修正しました。

  • [mruby] 本当のエラーが隠されていた問題を修正しました。mrubyは引数無しで投げられたエラーの伝搬に対応していません。mruby/mruby#290

  • [トークナイザー][TokenNgram loose]: クエリが曖昧な種類のみであった場合に検索結果が見つからない問題を修正しました。語彙表を伴っての highlight_html() も同様に壊れていました。

  • テキストから数値への変換において、後続するゴミ部分が無視されていた問題を修正しました。 "0garbage" は変換エラーになります。

  • reference_column >= 'key_value' に当てはまる場合の最適化の問題を修正しました。

8.0.5リリース - 2018-07-29#

改良#

  • [スクリプト構文] 類似文書検索の補足説明とその日本語訳を追加しました。 [GitHub groonga/GitHub#858] [堀本さんがパッチ提供]

  • [time_classify_day_of_week] 新しい関数 time_classify_day_of_week() を追加しました。

  • -fstack-protector で警告を抑制するようにしました。(OBATA Akioさんが提案)

  • 新しいAPI time_format_iso8601() を追加しました。

  • grn_raw_string 構造体を公開。

  • 新しいAPI: grn_obj_clear_option_values() を追加しました。永続的なデータベースのremoveと一時的なデータベースのcloseの際にオプションの値を消去できます。

  • [log] [ii][update][one] のエラーメッセージにインデックスカラム名を出力するようにしました。

  • [httpd] バンドルしているnginxのバージョンを1.15.2に更新しました。

  • [Ubuntu] Ubuntu 17.10 (Artful Aardvark)のサポートをやめました。2018年7月19日でサポートが切れた(EOLになった)ためです。

  • [Debian GNU/Linux] jessieのサポートをやめました。Debianのセキュリティ&リリースチームはもはやjessieの更新を提供しません。

修正#

  • POSTでの /d/load へのデータ送信が中断された後に誤った結果が返されていたのを修正しました。

  • KyTeaに関する間違った関数呼び出しを修正しました。

  • [grndb] --force-truncate オプションのラベルを追加しました。

  • groonga-normalizer-mysql のようにプラグインとして提供されているノーマライザーでオプションを使った場合に、データベースを終了するときにクラッシュする問題を修正しました。

  • ノーマライザーとトークナイザーのオプションが無視される場合があった問題を修正しました。この問題は同じオブジェクトIDが再利用された場合に発生していました。

8.0.4リリース - 2018-06-29#

改良#

  • [log] [ii][update][one] のエラーメッセージにサブエラーを追加しました。

  • 新しいAPI grn_highlighter_clear_keywords() を追加しました。

  • 新しいpredicate grn_obj_is_number_family_bulk() を追加しました。

  • 新しいAPI grn_plugin_proc_get_value_mode() を追加しました。

  • [vector_find] 新しい関数 vector_find() を追加しました。

  • msgpackでのmemcpyの警告を抑制しました。

  • mrubyを1.0.0から1.4.1に更新しました。

  • [doc][grn_obj] grn_obj_is_index_column() のAPIリファレンスを追加しました。

  • [windows] printfフォーマットの警告を抑制しました。

  • [windows] msgpackによる警告を抑制しました。

  • [grn_obj][Plugin] エンコーディングコンバーターを追加しました。ルール:

    • grn_ctx::errbuf: grn_encoding

    • grn_logger_put: grn_encoding

    • mruby: UTF-8

    • path: locale

  • [mrb] LocaleOutput を追加しました。

  • [windows] イメージのパスのgrn_encodingへの変換をサポートしました。

  • [トークナイザー][TokenMecab] エラーメッセージのエンコーディングを変換するようにしました。

  • [window_sum] 対象カラムとしての動的カラムをサポートしました。

  • [doc][grn_obj] grn_obj_is_vector_column() のAPIリファレンスを追加しました。

  • [column_create] より多くのバリデーションを追加しました。

    • 1: ベクターカラムの全文検索インデックスは WITH_SECTION フラグが必要です。(ただし、 WITH_POSITION あり、 WITH_SECTION なしのTokenDelmitは許容されます。これはタグ検索に便利なパターンです。)

    • 2: ベクターカラムの全文検索インデックスはマルチカラムインデックスであってはいけません。詳細: groonga/groonga

  • [grndb] 実装が不十分だったため、ログのチェックを一時的に無効にしました

修正#

  • [sub_filter] 十分にフィルターされたケースで、スコアが多すぎる問題を修正

  • KyTeaがインストールされているとビルドに失敗する問題を修正しました。

  • [grndb] 出力チャネルを修正しました。

  • [query-log][show-condition] クラッシュするバグを修正しました(まだ残っている可能性があります)。

  • [highlighter][lexicon] ハイライトされないバグを修正しました。キーワードの長さがN未満(N-gramのN。多くの場合はBigramなので2未満)の場合、キーワードがハイライトされていませんでした。

  • [windows] base path検出時の問題を修正しました。システムロケールのDLLパスが、CP932での「U+8868 CJK UNIFIED IDEOGRAPH-8868」のように0x5c (ASCIIでの \ )を含む場合に問題がありました。

  • [トークナイザー][TokenNgram] 最初の文字の長さの誤りを修正しました。この問題は、「U+3231 PARENTHESIZED IDEOGRAPH STOCK」のような「PARENTHESIZED IDEOGRAPH」文字で起きていました。

8.0.3リリース - 2018-05-29#

改良#

  • [highlight_html] NormalizerNFKC100 または TokenNgram を使って検索した結果のハイライトをサポートしました。

  • [トークナイザー] TokenNgram に新しいオプション report_source_location option を追加しました。このオプションは、highlight_html で語彙表を使ったハイライトをする時に使用します。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション unify_middle_dot option を追加しました。このオプションは、中点を正規化します。 の有無や 位置にかかわらず検索できます。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション unify_katakana_v_sounds option を追加しました。このオプションは、ヴァヴィヴヴェヴォバビブベボ へ正規化します。例えば バイオリンヴァイオリン で検索できます。

  • [ノーマライザー] NormalizerNFKC100 に新しいオプション unify_katakana_bu_sound option を追加しました。このオプションは、ヴァヴィヴゥヴェヴォ に正規化します。例えば、セーブルセーヴルセーヴェル で検索できます。

  • [sub_filter] 十分にフィルターされたケースでの sub_filter の動作を最適化しました。この最適化は、 sub_filter 実行前に十分にレコードが絞り込まれているケースで有効になります。

  • [groonga-httpd] 全てのワーカのコンテキストアドレスをユニークにしました。コンテキストアドレスは、以下のクエリーログの #{ID} です。

    #{TIME_STAMP}|#{MESSAGE}
    #{TIME_STAMP}|#{ID}|>#{QUERY}
    #{TIME_STAMP}|#{ID}|:#{ELAPSED_TIME} #{PROGRESS}
    #{TIME_STAMP}|#{ID}|<#{ELAPSED_TIME} #{RETURN_CODE}
  • [delete] 新しいオプション limit を追加しました。以下の例のように、削除するレコードの件数を制限できます。delete --table Users --filter '_key @^ "b"' --limit 4

  • [httpd] バンドルしているnginxのバージョンを1.14.0に更新しました。

修正#

  • [logical_select] 動的カラムをフィルターした時にエラーが発生するとメモリリークする不具合を修正しました。

  • [logical_count] 動的カラムの初期化に失敗した際にメモリリークする不具合を修正しました。

  • [logical_range_filter] 動的カラムの評価に失敗した際にメモリリークする不具合を修正しました。

  • [トークナイザー] loose_symbol のように緩いトークナイズをした時に source_offset が誤った値になる不具合を修正しました。

  • [ノーマライザー] U+FF21 FULLWIDTH LATIN CAPITAL LETTER A のような全角ラテン大文字が、U+0061 LATIN SMALL LETTER A のようなラテン小文字に正規化されない不具合を修正しました。すでに、 NormalizerNFKC100 を使用している場合は、インデックスを再生成する必要があります。

8.0.2リリース - 2018-04-29#

改良#

  • [grndb][--force-truncate] grndb recover --force-truncate オプションを指定することで、テーブルにロックが残ったままの状態でも truncate できるようにしました。

  • [logical_range_filter] sort_keys オプションに対応しました。

  • 新しい関数 time_format() を追加しました。Time 型のカラムの値を時刻表記で出力できます。書式は strftime 用の形式を指定できます。

  • [トークナイザー] 新しいトークナイザー TokenNgram を追加しました。このトークナイザーは、オプションを通じて挙動を動的に変えることができます。対応しているオプションは以下の通りです。

    • n : Ngram の「N」を指定します。例えば trigram の場合は「3」です。

    • loose_symbol : 記号を含む語句について、記号の有無の違いを無視して検索できるようにトークナイズします。例えば「090-1111-2222」という語句は、「09011112222」「090」「1111」「2222」「090-1111-2222」のいずれで検索した場合にも検索結果としてヒットするようになります。

    • loose_blank : 空白を含む語句について、空白の有無の違いを無視して検索できるようにトークナイズします。例えば「090 1111 2222」という語句は、「09011112222」「090」「1111」「2222」「090 1111 2222」のいずれで検索した場合にも検索結果としてヒットするようになります。

    • remove_blank : 空白を含む語句について、空白無しの語句で検索できるようにトークナイズします。例えば「090 1111 2222」という語句は、「09011112222」「090」「1111」「2222」のいずれで検索した場合にも検索結果としてヒットするようになります。空白を含む語句「090 1111 2222」での検索にはヒットしない点にご注意下さい。

  • [ノーマライザー] Unicode 10.0 の NFKC(Normalization Form Compatibility Composition)に基づくノーマライザーである "NormalizerNFKC100" を追加しました。

  • [ノーマライザー] ノーマライザーの "NormalizerNFKC51" と "NormalizerNFKC100" でのオプション指定に対応しました。ノーマライザーの挙動を動的に変えることができます。対応しているオプションは以下の通りです。

    • unify_kana : 同じ音となる全角ひらがな、全角カタカナ、半角カタカナの文字を同一視します。

    • unify_kana_case : 全角ひらがな、全角カタカナ、半角カタカナで拗音、促音などを表す小さな文字(例:「ぁ」「ゃ」「っ」)を大きな文字と同一視します。

    • unify_kana_voiced_sound_mark : 全角ひらがな、全角カタカナ、半角カタカナで濁点や半濁点の有無を同一視します。

    • unify_hyphen : ハイフンに類する文字すべてをハイフンと同一視します。

    • unify_prolonged_sound_mark : 長音記号に類する文字すべてを長音記号と同一視します。

    • unify_hyphen_and_prolonged_sound_mark : ハイフンに類する文字と長音記号に類する文字のすべてをハイフンと同一視します。

  • [dump] トークナイザーとノーマライザーのオプションの出力に対応しました。トークナイザーまたはノーマライザーのオプションを含んだ状態でGroonga 8.0.2およびそれ以降で出力した dump は、Grooga 8.0.1以前のバージョンでは読み込めず、未対応の情報によりエラーとなります。

  • [dump] トークナイザーとノーマライザーのオプションの出力に対応しました。トークナイザーまたはノーマライザーのオプションを含んだ状態でGroonga 8.0.2およびそれ以降で出力した schema は、Grooga 8.0.1以前のバージョンでは読み込めず、未対応の情報によりエラーとなります。

  • Ubuntu 18.04 (Bionic Beaver)をサポートしました。

修正#

  • スペースのみの検索クエリが意図しないレコードにマッチする不具合を修正しました。[groonga-dev,04609][satouyuzhさんの報告]

  • 誤ったスコアラーが使われる場合があった不具合を修正しました。この問題は以下のように複数のスコアラーが使われた時に発生していました: --match_columns 'title || scorer_tf_at_most(content, 2.0)'

  • 「thread_limit」の変更に時間がかかりすぎる問題を修正しました。

感謝#

  • satouyuzhさん

8.0.1リリース - 2018-03-29#

改良#

  • [ログ] クエリーログ内で filter 条件を表示するようにしました。この機能はデフォルトでは、無効になっています。有効にするためには、環境変数 GRN_QUERY_LOG_SHOW_CONDITION=yes を設定します。

  • *.pdb*.dll*.exe と同じディレクトリにインストールされるようにしました。

  • [logical_count] filtered ステージの動的カラムをサポートしました。

  • [logical_count] [post_filter] フィルタータイミングを新規追加しました。 filtered ステージのカラムが生成された後に実行されます。

  • [logical_select] [post_filter] フィルタータイミングを新規追加しました。 filtered ステージのカラムが生成された後に実行されます。

  • ベクターデータに対してLZ4/Zstd/zlibの圧縮をサポートしました。

  • _key のようなアクセサへのエイリアスをサポートしました。

  • [logical_range_filter] 大きい結果セットに対するウィンドウ関数の動作を最適化しました。一致するレコードが十分見つかった場合は、残りのウィンドウに対してウィンドウ関数を適用しません。

    TODO: この最適化は、最適化によるオーバーヘッドが無視出来ない場合、小さな結果セットに対しては、無効になります。 オーバーヘッドがどのくらいになるのかは、まだ評価出来ていません。

  • [select] match_escalation パラメーターを追加しました。--match_escalation yes とすることによって、マッチ演算のエスカレーションを強制的に有効にします。このパラメータは、 --match_escalation_threshold 99999....999 よりも強力です。match_escalation yes は、 SOME_CONDITIONS && column @ 'query' もエスカレーションしますが、 --match_escalation_threshold ではしないためです。

    デフォルトは、 --match_escalation auto です。これは、既存の動作と同じです。

    --match_escalation no とすることで、マッチ演算のエスカレーションを無効にできます。これは、 --match_escalation_threshold -1 と同様の動きになります。

  • [httpd] バンドルしているnginxのバージョンを1.13.10に更新しました。

修正#

  • 共通接頭辞がどのトークンにもマッチしない時にメモリリークする問題を修正しました。[GitHub#820] [村上さんがパッチ提供]

  • 同一プロセスで複数のデータベースを開いている時に、異なるデータベースのキャッシュを使用してしまう問題を修正しました。

  • 誤ったインデックスが構築される問題を修正しました。この問題は、インデックスカラムのソースがベクターカラムでかつ、 WITH_SECTION を指定していない時だけ発生します。

  • 比較時(>,>=,<,<=,==,!=)に定数がオーバーフローまたは、アンダーフローし得る問題を修正しました。

感謝#

  • 村上さん

8.0.0リリース - 2018-02-09#

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

改良#

  • [select] --drilldown_adjusterdrilldowns[LABEL].adjuster を追加しました。drilldown結果に対して、スコア調整できるようになります。

  • [動的なインデックス構築方法] 環境変数の名前を GRN_II_REDUCE_EXPIRE_ENABLE から GRN_II_REDUCE_EXPIRE_THRESHOLD へ変更しました。

    GRN_II_REDUCE_EXPIRE_THRESHOLD=0 == GRN_II_REDUCE_EXPIRE_ENABLE=noGRN_II_REDUCE_EXPIRE_THRESHOLD=-1 とすると、しきい値は ii->chunk->max_map_seg / 2 となります。GRN_II_REDUCE_EXPIRE_THRESHOLD > 0 とすると、しきい値は MIN(ii->chunk->max_map_seg / 2, GRN_II_REDUCE_EXPIRE_THRESHOLD) となります。デフォルト値は、 GRN_II_REDUCE_EXPIRE_THRESHOLD=32 です。

  • [between] 境界値なしの between() を受け付けるようにしました。between() の引数の数が3つでも実行できます。2番目と3番目の引数が境界を含むものとして処理されます。

修正#

  • ハッシュテーブルのメモリリークを修正しました。 [GitHub:mroonga/mroonga#190][fuku1さんの報告]

  • 配列のメモリリークを修正しました。

  • [select] output_columns で結果の変化する関数を使っている時にキャッシュしないようにしました。

  • [Windows] WSASend が適切なエラーコードを返すようにしました。

感謝#

  • fuku1さん

7.1.1リリース - 2018-01-29#

改良#

  • [Ubuntu] Ubuntu 17.04(Zesty Zapus)のサポートをやめました。2018年1月13日でサポートが切れた(EOLになった)ためです。

  • Quorum matchをサポートしました。スクリプト構文でもクエリー構文でもquorum matchを使うことができます。

    TODO: quorum matchの構文をドキュメントへ追加、それらのドキュメントへのリンク生成

  • スクリプト構文で類似度のカスタマイズをサポートしました。スクリプト構文内で類似度のカスタマイズができます。

    TODO: 類似度のカスタマイズの構文をドキュメントへ追加、それらのドキュメントへのリンク生成

  • [grndb][--force-lock-clear] --force-lock-clear を追加しました。このオプションは、データベースやテーブル、データカラムのロックを強制的に解除します。データベースやテーブル、データカラムにロックが残っていても再度データベースを使えるようになります。

    しかし、このオプションはとても危険です。通常は使うべきではありません。データベースが壊れている場合は、データベースは依然として破損しています。このオプションはロックを無視するだけです。

  • [load] サロゲートペアをエスケープ可能にしました。例えば、 \uD83C\uDF7A🍺 として処理されます。

  • [Windows] Windows上でスパースファイルを使用するように変更しました。ディスク容量を節約できます。パフォーマンス上のデメリットはありません。

  • [動的なインデックス構築方法] インデックスカラム内のメモリーマップをいつ開放するかをコントロールする環境変数 GRN_II_REDUCE_EXPIRE_THRESHOLD を追加しました。デフォルトは -1 です。 -1 のときはインデックスカラムのサイズによって動的に開放するタイミングを決めます。インデックスカラムが小さければ頻繁に解放し、大きければ頻度を下げます。

    0 を設定すると従来と同じ挙動になります。従来の挙動とは、Groongaは開放できそうなときはいつも開放しようとするという挙動です。

  • [logical_range_filter] [post_filter]フィルタータイミングを新規追加しました。 filtered ステージで生成されるカラムが生成された後に実行されます。

修正#

  • 参照ベクタのインデックスを作成する際に使用するリソースを削減しました。[GitHub#806][村上さんが報告]

  • [table_create] token_filters が無効であってもテーブルが作成される不具合を修正しました。

感謝#

  • 付超群さん

  • 村上さん

7.1.0リリース - 2017-12-29#

改良#

  • [load] load コマンドのクエリーログのフォーマットを改良しました。load コマンドのクエリーログに以下の項目が追加されます。

    • ロードしたレコード数を表示します。

    • ロードがエラーになったレコードとカラムの数を表示します。

    • ロード後の総レコード数を表示します。

  • [logical_count] logical_count コマンドのクエリーログのフォーマットを改良しました。logical_count コマンドのクエリーログに以下の項目が追加されます。

    • マッチしたレコード数を表示します。

  • [logical_select] logical_select コマンドのクエリーログのフォーマットを改良しました。 logical_select コマンドのクエリーログに以下の項目が追加されます。

    • マッチしたレコード数を表示します。

    • ドリルダウンした数を表示します。

    • ラベルつきのドリルダウンをした数を表示します。

    • それぞれのシャードで検索にマッチした数を表示します。

    • 検索対象のシャードの情報を"[...]"を使って表示します。

  • [delete] delete コマンドのクエリーログのフォーマットを改良しました。 delete コマンドのクエリーログに以下の項目が追加されます。

    • 削除したレコード数と削除に失敗したレコード数を表示します。

    • 削除後に残ったレコード数を表示します。

  • [Groonga HTTPサーバー] groonga -s で実行したサーバーをC-c で確実に停止出来るようにしました。

  • Lisp表現( #<nan>#i1/0#-i1/0 )の代わりに NanInfinity-Infinity を使用するように改良しました。

  • ドリルダウンでベクター型のカラムをサポートしました。

  • 部分的に正規表現を用いた検索から、キーワードを抽出出来るように改良しました。これにより、正規表現を用いた検索に highlight_htmlsnippet_html を使えるようになります。[takagi01さんに報告いただきました]

  • grn_bulk_*() APIにおいて、 realloc() が呼ばれる回数を削減しました。

    Windowsにおいて出力が大きいケースでパフォーマンスが向上します。例えば、出力が100MBを超える場合には、約100倍速くなります。

    realloc() はWindowsでは重い処理であるためです。

  • GRN_II_OVERLAP_TOKEN_SKIP_ENABLE の値にyesが設定された時のみ GRN_II_OVERLAP_TOKEN_SKIP_ENABLE を有効にするようにしました。

  • GRN_NGRAM_TOKENIZER_REMOVE_BLANK_DISABLE は非推奨になりました。代わりに GRN_NGRAM_TOKENIZER_REMOVE_BLANK_ENABL=no を使って下さい。

  • 関数 index_column_source_records を新規に追加しました。インデックスカラムのソースを取得することができます。[村上さんがパッチを提供]

  • [select] offsetに負の値を設定出来るようにしました。

  • 固定サイズのカラムの値を取得する際のパフォーマンスを向上しました。

  • [groonga 実行ファイル] groongaコマンドの引数に --listen-backlog オプションを追加しました。listenシステムコールのbacklogをカスタマイズできます。

  • [httpd] バンドルしているnginxのバージョンを1.13.8に更新しました。

修正#

  • highlight_full 関数を使用するとメモリリークする問題を修正しました。

  • Mroongaで以下ような呼び出しを行った際にクラッシュする問題を修正しました。

    1. grn_expr_append_const("_id")

    2. grn_expr_append_op(GRN_OP_GET_VALUE)

感謝#

  • takagi01

  • 村上さん

7.0.9リリース - 2017-11-29#

改良#

  • Apache Arrowの新しいバージョンをサポートしました。このリリースでは、Apache Arrowサポートを有効にするには0.8.0以降が必要です。

  • [sharding] 動的カラムの新しいAPIを追加しました。

    • Groonga::LabeledArguments

  • [sharding] 便利メソッドである Table#select_all を追加しました。

  • [logical_range_filter] 動的カラムをサポートしました。 initialfiltered ステージのみをサポートしています。

  • [logical_range_filter] cache 引数と動的カラムに関するドキュメントを追加しました。

  • [logical_count] 動的カラムをサポートしました。initial ステージのみサポートしています。

  • [logical_count] 名前付き引数のドキュメントを追加しました。

  • [select] --match_columns _key をインデックスを使わない場合でもサポートしました。

  • [in_values] 126を超える引数を指定できるようにしました。 [GitHub#760] [GitHub#781] [groonga-dev,04449] [むらたさんが報告]

  • [httpd] バンドルしているnginxのバージョンを1.13.7に更新しました。

修正#

  • [httpd] 古いバージョンのGroongaがすでにインストールされている場合にそちらを参照してしまい、ビルドエラーになる問題を修正しました。 [GitHub#775] [myamanishi3さんが報告]

  • [in_values] in_values に多すぎる引数を指定するとクラッシュする不具合を修正しました。この不具合は126を超える引数をサポートする過程で見つかりました。 [GitHub#780]

  • [cmake] LZ4 と MessagePack をビルド時に正しく検出できるようにしました。 [Sergei Golubchikさんが報告]

  • [静的なインデックス構築方法] ベクターカラムの静的索引構築時に必要以上のリソースを使用する問題を修正しました。1つのベクターカラムの要素数が多く、大量のレコードがある場合はGroongaがクラッシュしていました。 [groonga-dev,04533][内山敏郎さんが報告]

感謝#

  • むらたさん

  • myamanishi3さん

  • Sergei Golubchikさん

  • 内山敏郎さん

7.0.8リリース - 2017-10-29#

改良#

  • [windows] クラッシュした際にバックトレースを出せるようにしました。関数呼び出しだけでなく、ソースコードの該当行も可能な限り表示します。バックトレースのサポートにより、問題の素早い解決につながります。

  • QUERY_NO_SYNTAX_ERROR を指定してあれば "( )" を --query に指定して実行できるようにしました。 以前のバージョンでは、エラーになっていました。 [GitHub#767]

  • QUERY_NO_SYNTAX_ERROR を指定してあれば "(+)" を --query に指定して実行できるようにしました。 以前のバージョンでは、エラーになっていました。 [GitHub#767]

  • QUERY_NO_SYNTAX_ERROR を指定してあれば --query "~y" (~ではじまる)クエリーを実行できるようにしました。 以前のバージョンでは、エラーになっていました。 [GitHub#767]

  • expired のログレベルを info から debug に変更しました。 2017-10-29 14:05:34.123456|i| <0000000012345678:0> expired i=000000000B123456 max=10 (2/2) このメッセージはインデックスをメモリーにマップした後で開放されたときに記録されます。つまり、メモリーの使用状況に関するデバッグには有用ですが、通常の運用においては有用ではありません。そのためログレベルを debug に変更しました。

  • Ubuntu 17.10 Artful Aardvarkをサポート。

修正#

  • [dat] データベースを拡張する際、意図せず大きなファイルが(ワーストケースで)作成されてしまうことのある不具合を修正しました。この不具合はインデックスカラムを頻繁に作成/削除を繰り返したときに発生する可能性があります。7.0.7ではこの不具合に関連して"大量にキーを削除したケースで table_create に失敗する"問題を修正しましたが、その修正が不十分なケースに対応しました。

  • [logical_select] offsetlimit が複数のシャードに対して適用されたとき、実際よりも少ないレコードが返される不具合を修正しました。

7.0.7リリース - 2017-09-29#

改良#

  • QUERY_NO_SYNTAX_ERROR+ のみのクエリーに指定したときにも動作するようにしました。以前のバージョンではそのようなクエリーはエラーになっていました。

  • [httpd] バンドルしているnginxのバージョンを1.13.5に更新しました。

  • [dump] 引数のデフォルト値を構文のセクションに追加しました。

  • [コマンドバージョン] --default-command-version 3 に対応しました。

  • 関数呼び出し時に検索結果をキャッシュできるようにしました。ほとんどの関数の呼び出し結果はキャッシュされます。例外は now()rand() を使った場合です。標準でキャッシュするように振る舞いを変更したので、新たにAPIを追加しました。

    • grn_proc_set_is_stable() を追加。

    • grn_proc_is_stable() を追加。

    呼び出しごとに結果が異なる関数を新規に追加する場合、grn_proc_is_stable(ctx, proc, GRN_FALSE) を呼ばなければなりません。もし呼ばなかった場合には、検索結果がキャッシュされるので、期待と異なり誤った結果を返します。

修正#

  • [windows] database_unmap が実行される前のファイルハンドルのエラー処理を適切に行うようにしました。database_unmap 実行前にリクエストがキャンセルされた場合、排他制御部分が未初期化となる場合がありました。その場合、クラッシュしていました。

  • [トークナイザー] トークナイザー名のドキュメントを修正しました。TokenBigramIgnoreBlankSplitSymbolAlphaTokenBigramIgnoreBlankSplitSymbolAlphaDigit であるべきでした。

  • エラー時に空のファイルが残らないようにしました。

    以前のバージョンでは、空のファイルがエラー時に残っていました。

    再現するためのシナリオは以下です。:

    1. grn_fileinfo_open によりファイルの作成に成功する

    2. DO_MAP によりファイルマッピングに失敗する

    そのような場合、Groongaの管理下にないファイルのせいで「すでにファイルが存在します。」という別のエラーが発生します。そういったファイルは後始末の段階で削除すべきでした。

  • 短時間に多数の更新を行っている状況で検索した場合にクラッシュすることがある不具合を修正しました。

  • [table_create] 大量に削除されたキーがDATテーブルに存在する場合、table_create の実行に失敗する不具合を修正しました。

7.0.6リリース - 2017-08-29#

改良#

  • 前方一致検索を複数インデックスを指定してできるようになりました。 (例 --query "Foo*" --match_columns "TITLE_INDEX_COLUMN||BODY_INDEX_COLUMN")

  • [window_count] window_count 関数を追加しました。検索した結果にカウントした値を追加するのに使います。検索結果をもとに分析したり、カウント結果をもとにフィルタしたりすると便利です。

  • 以下のAPIを公開しました。

    • grn_obj_get_disk_usage() を追加。

    • GRN_EXPR_QUERY_NO_SYNTAX_ERROR を追加。

    • grn_expr_syntax_expand_query_by_table() を追加。

    • grn_table_find_reference_object() を追加。

  • [object_inspect] 指定したオブジェクトのディスク使用量を表示できるようになりました。

  • クエリーをパースする際にフォールバックする機能をサポートしました。 QUERY_NO_SYNTAX_ERROR フラグが query_flags に指定されていると有効になります。(標準では無効です) このフラグが設定されていると、シンタックスエラーが発生しなくなります。例えば、"A +" というクエリーは自動的にエスケープされて "A +" という扱いになります。この振る舞いはアプリケーションがユーザーの入力をそのまま検索語句として使い、シンタックスエラーやログに記録されないようにしたい場合に便利です。

  • クエリー内の語のスコアを調整できるようになりました。">", "<" と "~"がサポートされています。例えば ">Groonga" は "Groonga" のスコアをインクリメントします。"<Groonga" は "Groonga" のスコアをデクリメントします。"~Groonga" は検索結果についてマッチしたドキュメントのスコアをデクリメントします。"~" は検索結果そのものには影響しません。

  • テーブルを削除するときのパフォーマンスを改善しました。 thread_limit=1 する必要はありません。参照されているテーブルが存在するかチェックする処理をオブジェクトを開かなくてもできるようにしました。その結果としてパフォーマンスが改善しました。

  • [httpd] バンドルしているnginxのバージョンを1.13.4に更新しました。

修正#

  • [dump] 7番目の引数 ( --sort_hash_table )が名前無しだと無視される不具合を修正しました。

  • [schema] コマンドラインパラメータの誤りを修正しました。source であるべきところが sources になっていました。[groonga-dev,04449] [むらたさんが報告]

  • [ruby_eval] ruby_evalコマンドがシンタックスエラーのときにクラッシュする問題を修正しました。 [GitHub#751] [ryo-pinusさんがパッチ提供]

感謝#

  • murata satoshi

  • ryo-pinus

7.0.5リリース - 2017-07-29#

改良#

  • [httpd] バンドルしているnginxのバージョンを1.13.3に更新しました。セキュリティーに関する修正(CVE-2017-7529)を含んでいます。

  • [load] UInt64の最大値をロードできるようにしました。以前のバージョンでは意図せず0に変換されてしまっていました。

  • 以下のAPIを公開しました。

    • grn_window_get_size() [GitHub#725] [村上さんがパッチ提供]

  • [math_abs] 絶対値を計算するための math_abs() 関数を追加しました。 [GitHub#721]

  • grn_default_logger_set_path()grn_default_query_logger_set_path() をスレッドセーフにしました。

  • [Windows] バンドルしているpcreを8.41に更新しました。

  • [normalize] エラー時に冗長な空文字列が出力されないようにしました。

  • [functions/time] 0除算が発生したときにエラーメッセージを出力するようにしました。 [GitHub#733] [村上さんがパッチ提供]

  • [windows] ERROR_NO_SYSTEM_RESOURCES エラーを GRN_RESOURCE_TEMPORARILY_UNAVAILABLE にマッピングするようにしました。以前は rc=-1 をエラーコードとして返していました。ただし実際にどんな問題がおきたのかこれではわかりにくいので、 今回の修正では rc=-12 を返すようにしています。

  • [functions/min][functions/max] ベクターカラムをサポートしました。これでカラムがスカラーなのかベクターなのか気にせず使えるようになりました。 [GitHub#735] [村上さんがパッチ提供]

  • [dump] --sort_hash_table オプションをサポートしました。ハッシュテーブルの _key でのソートには --sort_hash_table yes を指定します。

  • [between] インデックスカラムを指定できるようになりました。 [GitHub#740] [村上さんがパッチ提供]

  • [load] Apache Arrow 0.5.0 以降をサポート。

  • [エラーメッセージの解析方法] エラーメッセージの解析方法のドキュメントを追加しました。

  • [Debian GNU/Linux] ソースからビルドするときに必要なパッケージのリストを更新しました。

  • [Ubuntu] Ubuntu 16.10(Yakkety Yak)のサポートをやめました。2017年7月20日でサポートが切れた(EOLになった)ためです。

修正#

  • テキスト型( ShortText など)のベクターカラムに対するインデックスを正しく構築できるようにしました。この修正でインデックス更新後に全文検索でマッチしない問題が解決します。 [GitHub#494]

  • [thread_limit] thread_limit?max=1 というリクエストが同時にきたときにデッドロックが発生する問題を修正しました。

  • [groonga-httpd] デフォルトのPIDのパスと再起動時に想定しているPIDのパスがあっていない問題を修正しました。そのせいで groonga-httpd の再起動に失敗していました。 [GitHub#743] [sozakiさんが報告]

感謝#

  • 村上さん

7.0.4リリース - 2017-06-29#

改良#

  • 物理的なファイルの作成/削除のログを障害の切り分けのために記録するようにしました。 [GitHub#700,#701]

  • [in_records] 固定長カラムの検索パフォーマンスを改善しました。速度が50%程度改善する可能性があります。

  • [grndb] --log-path オプションを追加しました。

  • [grndb] --log-level オプションを追加しました。

  • 以下のAPIを公開しました。

    • grn_operator_to_exec_func()

    • grn_obj_is_corrupt()

  • "固定長カラム 演算子 定数" というようなクエリのパフォーマンスを改善しました。対応している演算子は ==, !=, <, >, <=>= です。

  • "カラム 演算子 値 && カラム 演算子 値 && ..." というようなクエリのパフォーマンスを改善しました。

  • [grndb] grndb check で壊れたオブジェクトの検出をサポートしました。

  • [io_flush] --only_opened オプションをサポートしました。開いているデータベースオブジェクトのみをフラッシュすることができます。

  • [grndb] 参照先のない "inspect" オブジェクトの検出と削除をサポートしました。この状態はコマンド名が inspect から object_inspect に変更されたことによって発生していました。

修正#

  • [rpm][centos] カスタマイズ版のビルドで意図しないマクロ展開が発生する問題を修正しました。この不具合はGroongaをSRPMからビルドする際にspecファイルの additional_configure_options パラメータを使ってリビルドするときのみ発生していました。

  • grn_table_setoperation() のNULLチェックを追加しました。インデックスが壊れている際に、クラッシュする可能性がありました。 [GitHub#699]

感謝#

7.0.3リリース - 2017-05-29#

改良#

  • [select] インデックス名を指定した全文検索 のドキュメントを追加しました。

  • [インデックス] どのレコードに対するポスティングリストが長すぎるのかわかるように、警告メッセージをログに出すようにしました。

  • [load][dump] Apache Arrowをサポートするようにしました。 [GitHub#691]

  • [cmake] 静的ライブラリとしてビルドする際に、LZ4をリンクできるようにしました。 [Sergei Golubchikさんがパッチを提供]

  • [delete] キャンセルできるようにしました。

  • [httpd] バンドルしているnginxのバージョンを1.13.0に更新しました。

  • 以下のAPIを公開しました。

    • grn_plugin_proc_get_caller() を追加。

  • インデックスカラムに関連した関数とセレクタを追加しました。

    • 追加されたセレクタ: index_column_df_ratio_between()

    • 追加された関数: index_column_df_ratio()

修正#

  • [delete] エラーが適切にクリアされていない不具合を修正しました。そのせいで、後続の削除処理に影響し意図しない振る舞いをしていました。

  • [windows] ファイルを O_CREAT フラグ付きで開くときに、IOのバージョンが正しく検出されない不具合を修正しました。

  • [vector_slice] (型のサイズが)4バイトでないベクターカラムをsliceできない不具合を修正しました。 [GitHub#695] [村上さんがパッチ提供]

  • (型のサイズが)4バイトでないベクターカラムでベクターの要素をインデックスで指定するとシーケンシャルサーチでマッチしない不具合を修正しました。 [GitHub#696] [村上さんがパッチ提供]

  • [logical_select] min に月の最終日を指定すると "argument out of range" が発生する不具合を修正しました。

感謝#

  • Sergei Golubchikさん

  • 村上さん

7.0.2リリース - 2017-04-29#

改良#

  • [logical_select] drilldowns[${LABEL}].columns[${NAME}].window.sort_keysdrilldowns[${LABEL}].columns[${NAME}].window.group_keys で複数のキーを指定できるようになりました。

  • [Windows] バンドルしているLZ4を1.7.5に更新しました。

  • [cache] 永続化キャッシュをサポートしました。

  • [log_level] 英語のドキュメントを更新しました。

  • 以下のAPIを公開しました。

    • grn_set_default_cache_base_path()

    • grn_get_default_cache_base_path()

    • grn_persistent_cache_open()

    • grn_cache_default_open()

  • [groonga --cache-base-path] 永続キャッシュを使うための新しいオプションを追加しました。

  • [groonga-httpd] [groonga_cache_base_path] 永続キャッシュを使うための新しい設定を追加しました。

  • [Windows] バンドルしているmsgpackを2.1.1に更新しました。

  • [object_inspect] カラム情報を表示するだけでなく、インデックスカラムの統計情報も表示できるようにしました。

  • 正規表現の「 .* 」というパターンでインデックスを使って検索できるようになりました。 この機能はデフォルトで有効です。環境変数に GRN_SCAN_INFO_REGEXP_DOT_ASTERISK_ENABLE=no を設定すると無効化できます。

  • [in_records] 既存のテーブルを条件のパターンを指定するのに使うことのできる関数を追加しました。

  • [Ubuntu] EOLのため、Ubuntu 12.04のサポートをやめました。

修正#

  • [logical_select] 異なるキャッシュが使われてしまう不具合を修正しました。この問題は動的カラムを使っているときに発生していました。

  • [logical_select] 動的カラムが作成されない不具合を修正しました。レコードにマッチしない場合に発生していました。

  • [reindex] reindexコマンドの実行によりデータが失われてしまう不具合を修正しました。

  • [httpd] 別のユーザーでワーカーを動かしている時、 quitshutdown のレスポンスが壊れている問題を修正しました。 [GitHub ranguba/groonga-client#12]

7.0.1リリース - 2017-03-29#

改良#

  • 以下のAPIを公開しました。

    • grn_ii_cursor_next_pos()

    • grn_table_apply_expr()

    • grn_obj_is_data_column()

    • grn_obj_is_expr()

    • grn_obj_is_scalar_column()

  • [column_copy] 参照型のベクタのダンプをサポートしました。

  • [load] array<object> スタイルの重み付きベクターカラムのloadをサポートしました。 array<object> の例: [{"key1": weight1}, {"key2": weight2}]

  • インデックスを使った !(XXX OPERATOR VALUE) の検索をサポートしました。演算子として > だけでなく、 >=<<===!= も使えます。

  • インデックスを使って !(column == CONSTANT) を検索できるようになりました。例えば !(column == 29) などです。

  • ! の最適化を以下のパターンでサポートしました。

    • !(column @ "X") && (column @ "Y")

    • (column @ "Y") && !(column @ "X")

    • (column @ "Y") &! !(column @ "X")

  • XXX || !(column @ "xxx") をインデックスを使って検索できるようになりました。

  • [dump] '{"x": 1, "y": 2}' というスタイルを参照されていない重み付きベクターカラムで使うようにしました。この変更は古いGroongaには影響しません。もともとサポートされているからです。

  • [実験的] GRN_ORDER_BY_ESTIMATED_SIZE_ENABLE 環境変数をサポートしました。この変数はクエリの最適化を予想されるヒット件数に応じて行うかどうかを切り替えるのに使用します。この機能はデフォルトでは無効です。有効にするには GRN_ORDER_BY_ESTIMATED_SIZE_ENABLE=yes を指定します。

  • [select] columnsdrilldown の評価結果をクエリログに追加するようにしました。

  • [select] drilldown のクエリログのフォーマットを変更しました。これは非互換な変更ですが、クエリログを変換するようなプログラムを独自に開発しているユーザー以外には影響ありません。

  • [table_remove] 一時的なメモリ使用量を削減しました。スレッドの最大数が0のときに有効になります。

  • [select] columns[LABEL](N) がクエリログのフォーマットとして使われます。以前は columns(N)[LABEL] でした。

  • [クエリ拡張] ベクターカラムを使った推奨例に更新しました。[ぐるなびさんが報告]

  • ロック中にリクエストがキャンセルされたことを検出できるようにしました。これは request_cancel がロック中に意図せず無視されないようにします。

  • [logical_select] initial および filtered 動的カラムをサポートしました。使用例は --columns[LABEL].stage initial--columns[LABEL].stage filtered です。

  • [logical_select] match_columnsquerydrilldown_filter オプションをサポートしました。

  • [highlight_html] 類似文書検索をサポートしました。

  • [logical_select] initial および filtered 動的カラムをサポートしました。使用例は --columns[LABEL].stage initial--columns[LABEL].stage filtered です。

  • [logical_select] 動的カラムでウィンドウ関数をサポートしました。

  • [select] 動的カラムに関するドキュメントを追加しました。

  • [ウィンドウ関数] ウィンドウ関数のセクションをドキュメントに追加しました。

  • [CentOS] EOLのため、CentOS 5のサポートをやめました。

  • [httpd] バンドルしているnginxのバージョンを1.11.12に更新しました。

  • ANDでのマッチ最適化を環境変数で無効化できるようにしました。この機能は GRN_TABLE_SELECT_AND_MIN_SKIP_ENABLE=no を設定することで無効化できます。デフォルトでは有効になっています。

  • [vector_new] 新規ベクターを作成するための関数を追加しました。

  • [select] drilldown_filter のドキュメントを追加しました。

修正#

  • [lock_clear] テンポラリデータベースに対して実行するとクラッシュする不具合を修正しました。

  • 自然言語に対する動的インデックス更新でインデックスサイズが肥大化する問題を修正しました。Groonga 6.1.4から発生していました。

  • [select] "A && B.C @ X" というクエリでマッチすべきレコードを返さないことがある不具合を修正しました。

  • grn_io_flush()grn_io_expire() がコンフリクトする問題を修正しました。この修正がないと、 io_flushload が同時に特定のタイミングで実行されるとクラッシュする不具合がありました。

  • [logical_table_remove] 最大スレッド数が1のときにクラッシュする不具合を修正しました。

感謝#

  • 株式会社ぐるなびさん

7.0.0リリース - 2017-02-09#

改良#

  • [in_values] 参照型ベクターカラムのシーケンシャルサーチに対応しました。 [GitHub#629] [村上さんがパッチ提供]

  • [select] 誤った drilldown[LABEL].sort_keys が指定されたとき、無視するのではなく、エラーを報告するようにしました。

  • [select] DBのメタデータを不必要に更新しないようにしました。 select コマンドを使っているだけなのにDBにロックがかかったままになってしまうのを防ぎます。

  • [lock_clear] lock_clear でDBのメタデータに対するロックも削除できるようにしました。

  • [CentOS] GroongaをAmazon LinuxでもインストールできるようにEPELをデフォルトで有効にするようにしました。

  • [query] default_mode オプションで "@X" スタイルのエイリアスが使えるようになりました。

  • [query] 動作モードのリストに関するドキュメントを更新しました。動作モードの既定値は MATCH ("@") で全文検索を実行します。

  • [rpm][centos] CentOS 7で groonga-token-filter-stem パッケージを提供するようにしました。 ステミングに対応するための TokenFilterStem トークンフィルターを提供します。 [GitHub#633] [Tim Bellefleurさんが報告]

  • [window_record_number] record_number が非推奨になりました。代わりに window_record_number を使ってください。 record_number は互換性のためだけに残っています。

  • [window_sum] window_sum ウィンドウ関数を追加しました。PostgreSQLのsum()と同様のウィンドウ関数を提供します。

  • TABLE_DAT_KEY テーブルをインメモリで使ったときに静的インデックス構築をできるようにしました。 [GitHub#623] [村上さんが報告]

  • バンドルしている鬼雲を6.1.1へと更新しました。

  • columns[LABEL].window.group_keys をサポートしました。ウィンドウ関数をグループごとに提供することができます。

  • [load] 誤ったキーが指定されていたときにエラーを報告するようにしました。キーの型が異なっている場合でも気付けるようになります。

  • [load] --output_errors yes オプションをサポートしました。"yes"を指定すると、どのレコードのloadに失敗したのかエラーを取得できるようになります。この機能を使う場合には、コマンドバージョン3を指定します。

  • [load] キーのキャストに失敗したときのエラーメッセージをわかりやすくしました。以前は単に "cast failed" と表示していましたが、テーブルのキーの型とキャスト対象となるキーの型もメッセージに含まれるようになりました。

  • [httpd] バンドルしているnginxのバージョンを1.11.9に更新しました。

修正#

  • 存在しないソートキーを drilldowns[LABEL]slices[LABEL] に指定するとJSONパースエラーとなる不具合を修正しました。 [GitHub#627] [村上さんがパッチ提供]

  • 存在しないグループのサブレコードにアクセスしようとするとクラッシュする不具合を修正しました。例えば、 drilldowns[LABEL].sort_keys _sumcalc_types の指定なしに使っていた場合に問題が発生していました。 [GitHub#625] [村上さんがパッチ提供]

  • tokenizerでエラーが発生するとクラッシュする不具合を修正しました。tokenizer と token filterを登録していて、tokenizer にエラーがあると発生していました。

  • [window_record_number] ウィンドウ関数の引数が正しく渡されていない不具合を修正しました。 [GitHub#634] [村上さんがパッチ提供]

感謝#

  • 村上さん

  • aomi-nさん

古いリリース#