BloGroonga

2023-10-31

Groonga 13.0.9リリース

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

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

変更内容

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

改良

  • [select] --fuzzy_max_expansions のデフォルト値を0から10に変更しました。

    --fuzzy_max_expansions を使うことで検索に使う編集距離の近い語の数を制限できます。 この引数はヒット数と検索パフォーマンスのバランスを取るための引数です。(編集距離の近い語が多すぎると検索速度が遅くなるため、上限を設定できるようにして検索が遅くなりすぎないようにできます。)

    --fuzzy_max_expansions のデフォルト値は0でしたが、 0の場合は語彙表にある編集距離が --fuzzy_max_distance 以下の語すべてを使って検索するため、この引数をそのまま使うと検索が遅くなるケースが出てきてしまいます。そのため、今回のリリースから --fuzzy_max_distance のデフォルト値を0から10に変更しました。

  • [select] select コマンドの引数に新しく --fuzzy_with_transposition を追加しました。(実験的)

    「隣接する文字の交換」の編集距離はデフォルトでは1ですが、この引数を使うことで「隣接する文字の交換」の編集距離を1または2に指定できます。

    --fuzzy_with_transpositionyes の場合、文字の交換の編集距離は 1 になります。 それ以外の値が指定された場合は、「隣接する文字の交換」の編集距離が2になります。

    通常のユースケースでは、 --fuzzy_with_transposition を操作する必要はありません。

  • [select] select の引数に新しく --fuzzy_tokenize を追加しました。(実験的)

    --fuzzy_tokenizeyes の時、Groongaは誤字を許容する検索で --default_tokenizer で指定したトークナイザーを使います。 --fuzzy_tokenize のデフォルト値は no です。--fuzzy_tokenize が有用なケースは、以下のケースです。

    誤字を許容する検索では、検索キーワードをどのようにトークナイズするは重要なポイントの1つです。 アルファベット等のASCII文字は、"Thjs is a pen" なら "Thjs", "is", "a", "pen" と分割されるので、"Thjs"を "This"として検索することができます。 ただ、日本語はスペース区切りの言語ではないため、デフォルトのトークナイザーでは、意味のある塊に検索キーワードを分割できません。 日本語の場合は、日本語に特化したトークナイザーを指定したくなります。 --fuzzy_tokenize はこのように、検索対象の言語によってトークナイザーを変更するための引数です。

    検索対象が日本語のデータのみの場合は、 --default_tokenizerTokenMecab を指定することで、日本語でも誤字を許容した検索が可能になります。

  • [ノーマライザー] NormalizerNFKC* に新しく remove_blank_force オプションを追加しました。

    remove_blank_forcefalse の時は、以下のようにノーマライザーは空白を無視しません。

    table_create Entries TABLE_NO_KEY
    column_create Entries body COLUMN_SCALAR ShortText
    
    load --table Entries
    [
    {"body": "Groonga はとても速い"},
    {"body": "Groongaはとても速い"}
    ]
    
    select Entries --output_columns \
      'highlight(body, \
        "gaはとても", "<keyword>", "</keyword>", \
        {"normalizers": "NormalizerNFKC150(\\"remove_blank_force\\", false)"} \
      )'
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            2
          ],
          [
            [
              "highlight",
              null
            ]
          ],
          [
            "Groonga はとても速い"
          ],
          [
            "Groon<keyword>gaはとても</keyword>速い"
          ]
        ]
      ]
    ]
    
  • [select] select コマンドの引数に新しく --output_trace_log を追加しました。(実験的)

    --output_trace_logyes を指定し --command_version 3 を指定した場合、Groongaは以下のようなログを新規に出力します。

    table_create Memos TABLE_NO_KEY
    column_create Memos content COLUMN_SCALAR ShortText
    
    table_create Lexicon TABLE_PAT_KEY ShortText   --default_tokenizer TokenNgram   --normalizer NormalizerNFKC150
    column_create Lexicon memos_content   COLUMN_INDEX|WITH_POSITION Memos content
    
    load --table Memos
    [
    {"content": "This is a pen"},
    {"content": "That is a pen"},
    {"content": "They are pens"}
    ]
    
    select Memos \
      --match_columns content \
      --query "Thas OR ere" \
      --fuzzy_max_distance 1 \
      --output_columns *,_score \
      --command_version 3 \
      --output_trace_log yes \
    --output_type apache-arrow
    
    return_code: int32
    start_time: timestamp[ns]
    elapsed_time: double
    error_message: string
    error_file: string
    error_line: uint32
    error_function: string
    error_input_file: string
    error_input_line: int32
    error_input_command: string
    -- metadata --
    GROONGA:data_type: metadata
    	return_code	               start_time	elapsed_time	error_message	error_file	error_line	error_function	error_input_file	error_input_line	error_input_command
    0	          0	1970-01-01T09:00:00+09:00	    0.000000	       (null)	    (null)	    (null)	        (null)	          (null)	          (null)	             (null)
    ========================================
    depth: uint16
    sequence: uint16
    name: string
    value: dense_union<0: uint32=0, 1: string=1>
    elapsed_time: uint64
    -- metadata --
    GROONGA:data_type: trace_log
    	depth	sequence	name	value	elapsed_time
     0	    1	       0	ii.select.input	Thas 	           0
     1	    2	       0	ii.select.exact.n_hits	    0	           1
     2	    2	       0	ii.select.fuzzy.input	Thas 	           2
     3	    2	       1	ii.select.fuzzy.input.actual	that 	           3
     4	    2	       2	ii.select.fuzzy.input.actual	this 	           4
     5	    2	       3	ii.select.fuzzy.n_hits	    2	           5
     6	    1	       1	ii.select.n_hits	    2	           6
     7	    1	       0	ii.select.input	ere  	           7
     8	    2	       0	ii.select.exact.n_hits	    2	           8
     9	    1	       1	ii.select.n_hits	    2	           9
    ========================================
    content: string
    _score: double
    -- metadata --
    GROONGA:n_hits: 2
    	content	    _score
    0	This is a pen	  1.000000
    1	That is a pen	  1.000000
    

    --output_trace_log は、コマンドバージョン3でのみ有効です。

    以下のケースで有用です。:

    • 誤字を許容する検索で使われた実際のキーワードの検知。
    • クエリーログを見ずに実行時間を測定。
  • [snippet] normalizers オプションをサポートしました。

    オプション付きのノーマライザーが使えるようになります。例えば、以下のように snippet() 関数内でスペースを無視したくない時にこのオプションを使います。

    table_create Entries TABLE_NO_KEY
    column_create Entries content COLUMN_SCALAR ShortText
    
    load --table Entries
    [
    {"content": "Groonga and MySQL"},
    {"content": "Groonga and My SQL"}
    ]
    
    select Entries \
      --output_columns \
        '   snippet(content,   "MySQL", "<keyword>", "</keyword>",   {"normalizers": "NormalizerNFKC150(\\"remove_blank_force\\", false)"}   )'
    [
      [
        0,
        0.0,
        0.0
      ],
      [
        [
          [
            2
          ],
          [
            [
              "snippet",
              null
            ]
          ],
          [
            [
              "Groonga and <keyword>MySQL</keyword>"
            ]
          ],
          [
            null
          ]
        ]
      ]
    ]
    

修正

  • Time OPERATOR Float{,32} が正しく評価されない問題を修正しました。 GH-1624[Reported by yssrku]

    Float{,32} 内のマイクロ秒(秒未満の小さい値)が使えていませんでした。この問題は Time OPERATOR Float{,32} の時だけ発生します。 以下のように、 load --ifexists 'A OP B || C OP D' でこの問題は発生します。

    table_create Reports TABLE_HASH_KEY ShortText
    column_create Reports content COLUMN_SCALAR Text
    column_create Reports modified_at COLUMN_SCALAR Time
    
    load --table Reports
    [
    {"_key": "a", "content": "", "modified_at": 1663989875.438}
    ]
    
    load \
      --table Reports \
      --ifexists 'content == "" && modified_at <= 1663989875.437'
    

    しかし、 select --filter では発生しません。

  • alnum(a-zA-Z0-9) + blank が検知されることがある問題を修正しました。

    この問題が発生すると以下のように highlight() で意図しない結果になります。

    table_create Entries TABLE_NO_KEY
    column_create Entries body COLUMN_SCALAR ShortText
    
    load --table Entries
    [
    {"body": "Groonga is fast"}
    ]
    
    select Entries \
      --output_columns 'highlight(body, "ai", "<keyword>", "</keyword>")'
    
    [
      [
        0,0.0,0.0
      ],
      [
        [
          [
            1
          ],
          [
            [
              "highlight",
              null
            ]
          ],
          [
            "Groong<keyword>a i</keyword>s fast"
          ]
        ]
      ]
    ]
    

    しかし、上記の結果は期待していない結果です。上記ケースでは a i は検知してほしくありません。