BloGroonga

2022-11-22

グルカイ!第24回「ドリルダウンの仕組みについて」を開催しました!

グルカイ!第24回「ドリルダウンの仕組みについて」の内容をまとめました!

今回は、ドリルダウンの仕組みについて解説いただきました! 解説時に使用した図はこちらです。

  • ドリルダウンとは?

    指定したキーの値でグループ化して、各グループに何件のレコードがあるかを集計できます。 これをつかうことで、0件のグループを表示しなくても良くなり、ユーザーに無駄な動作をさせなくてすむようになります。

  • ドリルダウンには複数のキーを指定できますが、同じキーを指定するとどうなるのか?同じキーを指定するようなユースケースはあるのか?

    基本的にそのようなユースケースはありません。同じキーを指定して使うようなことはしません。

    ドリルダウンは、ある特定のデータに着目してより詳細な集計をすることができます。(例えば、ある特定の商品の特定の年度の売上を見たい等。) 全文検索では特定のレコードを見つける必要がありますが、ドリルダウンではどういった傾向があるのかを把握するということができます。 着目したい点が複数ある場合に複数のキーを使うので、同じキーを使う意味がありません。

  • _valueで値が取得できるのは、どういう仕組みなのか?

    Groongaは検索結果を一時的なテーブルに保持しています。 この一時テーブルは、_keyというカラムが必ずあります。_keyはRDBMSでいう主キーです。 ドリルダウンの時はこの_keyには、ドリルダウンのキーが入ります。ドリルダウンのキーが複数ある場合は、_keyはvectorになります。 この時 _key にアクセスするとすべてのキーが取得できます。_keyはvectorなので、最初の要素を取得するには_key[0]でアクセスできます。

    複数のドリルダウンのキーを指定した場合は、_valueにはレコードIDが入っています。 _valueはレコードが取得できるので、ドリルダウンのキー以外の値を取得できます。_keyではどの値をドリルダウンのキーにしたかしかわかりませんが_valueでは、ドリルダウンのキー以外の値も取得できます。

2022-11-15

グルカイ!第23回「Groonga関連プロダクトのコンセプトについて」を開催しました!

グルカイ!23回 「Groonga関連プロダクトのコンセプトについて」の内容をまとめました!

今回は、Groonga関連プロダクトのコンセプト(何を大事に開発しているか)について解説いただきました!

  • Groongaが大事にしていること。

    • 情報の鮮度。登録された情報を即時検索できる。
    • 検索速度
    • ユーザーが欲しい情報を見つけるのを支援する。
      • ユーザーが情報を見つけられないと意味がないため。
      • ドリルダウンを高速にする等。
  • Mroonga/PGroongaが大事にしていること。

    • 使いやすさ。 全文検索は使い始めるのも使いこなすのも難しい。 最近はWebアプリケーションを作る人は多く、Webアプリケーションを作る時はライブラリーやフレームワークを使って作成します。 これらのライブラリーやフレームワークにはRDBMSへのアクセスがしやすいような機能がついているが、全文検索エンジンにはそういったサポートはありません。 全文検索エンジンは、ユーザーが知るべきことが多いので使いにくいところがあります。。(初期コストも大きい。メンテナンスコストも大きい。) WebアプリケーションのフレームワークにはRDBMSサポートが組み込まれているので、その知識+αくらいで全文検索エンジンも使えると使いやすいと考えています。 普段、MySQL/PostgreSQLを使っている人が使いやすいということを狙ったプロダクトです。

      Groonga単体を使うというのもありですが、学習コストが高いので万人に受けるわけではありません。 普段MySQL/PostgreSQLを使っている人からも使いやすいようになっています。

      例えばMroongaでは、MySQLの既存機能と馴染むように作っています。 MySQLには全文検索用のSQLの構文(MATCH AGAINST)があるので、それを使ってGroongaを使った全文検索ができるようにしています。 MATCH AGAINST はMySQLの標準機能なので、 Webアプリケーションのフレームワークのサポートも期待できます。 インデックスの作成もMySQLの標準機能を使ってできるようにしています。

      拡張をする場合もなるべくMySQLの既存の仕組みに乗せるようにしています。

  • ラングバとは?

    • 文書検索ラングバ:クローラーで文書を取得して、UIも作れる、ChpaTextでテキスト抽出してRroongaで登録して全文検索できるようにするシステムです。
    • RroongaはRubyからGroongaを使えるようにするプロダクトです。Mroonga、PGroongaと同様Rubyと馴染むように作っています。
    • ActiveGroonga, ActiveGroonga Fabrication はm現状メンテナンスできてないません。 (ActiveRecordと同じように使えるようにしていたが、ActiveRecordの開発速度が早すぎてメンテナンスが追いついていません。)
    • ChupaText:テキストデータでないものからテキストを抽出する。テキストにすることで全文検索の対象にできるためです。
2022-10-31

PostgreSQL用高速日本語全文検索モジュールPGroonga(ぴーじーるんが) 2.4.1リリース

PostgreSQLで高速日本語全文検索をできるようにするPGroongaの2.4.1をリリースしました!

新規ユーザーの方は、PGroonga 2.0.2のリリースアナウンスのPGroongaについても参照してください。

ハイライト

PGroonga 2.4.1の主な変更点は以下の通りです。:

  • PostgreSQL 15 をサポートしました。

  • PostgreSQL 10 のサポートを終了しました。

    PostgreSQL 10 は、2022年11月にEOLになるためです。

  • [jsonb型用の &@~ 演算子] jsonb型の値をインデックスを使って検索する方法の日本語訳を追加しました。

まとめ

PostgreSQLで高速に日本語全文検索をしたいという方はPGroongaを使ってガンガン検索してください!

2022-10-31

Groonga 12.0.9リリース

Groonga 12.0.9をリリースしました!

それぞれの環境毎のインストール方法: インストール

変更内容

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

改良

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

    Groonga 12.0.8 でサポートしていましたが、アナウンスしていませんでした。

  • 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がクラッシュしたり誤った値を返すことがありました。

既知の問題

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

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

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

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

さいごに

詳細については、以下のお知らせ、リリース自慢会も参照してください。

お知らせ 12.0.9リリース

リリース自慢会

リリース自慢会は、リリースノートを見ながら、Groongaの新機能・バグ修正を開発者が自慢する会です。

毎月リリースされている最新バージョンについて、開発者的に「これ!」という機能や、「ここをがんばった!」ということを紹介しています。 Liveチャットでコメントも受け付けていますので、気になっていることを質問したり、気になっていたあの機能について聞いたりすることも可能です。

それでは、Groongaでガンガン検索してください!

2022-10-07

PostgreSQL用高速日本語全文検索モジュールPGroonga(ぴーじーるんが) 2.4.0リリース

PostgreSQLで高速日本語全文検索をできるようにするPGroongaの2.4.0をリリースしました!

新規ユーザーの方は、PGroonga 2.0.2のリリースアナウンスのPGroongaについても参照してください。

ハイライト

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

  • Ubuntu Ubuntu 22.04 (Jammy Jellyfish) で PGDG PostgreSQL 10, 11, 12, 13, 14 をサポートしました。

まとめ

PostgreSQLで高速に日本語全文検索をしたいという方はPGroongaを使ってガンガン検索してください!

2022-10-03

Groonga 12.0.8リリース

Groonga 12.0.8をリリースしました!

それぞれの環境毎のインストール方法: インストール

変更内容

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

改良

  • 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 CMakeを使ってビルドする方法を追加しました。

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

  • select drilldowns.table のドキュメントを追加しました。

  • i18n 翻訳方法を更新しました。

改良

  • 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\"} にマッチしていました。

既知の問題

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

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

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

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

さいごに

詳細については、以下のお知らせ、リリース自慢会も参照してください。

お知らせ 12.0.8リリース

リリース自慢会

リリース自慢会は、リリースノートを見ながら、Groongaの新機能・バグ修正を開発者が自慢する会です。

毎月リリースされている最新バージョンについて、開発者的に「これ!」という機能や、「ここをがんばった!」ということを紹介しています。 Liveチャットでコメントも受け付けていますので、気になっていることを質問したり、気になっていたあの機能について聞いたりすることも可能です。

それでは、Groongaでガンガン検索してください!