BloGroonga

2017-11-29

Groonga 7.0.9リリース

今日は肉の日ですね!

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

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

変更内容

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

in_valuesで126を超える引数を指定できるようにしました

これまでのバージョンでは、 in_values の引数は126個までという制限がありました。 そのため、多数の OR== を使っているクエリを in_values を使ってまとめようとしても、引数の個数の制限のためできない置き換えられない場合がありました。

今回のリリースでは、その制限を撤廃したので、上限を気にすることなく in_values を使えるようになりました。

logical_range_filterlogical_countにて動的カラムをサポートしました

selectlogical_select だけでなく、logical_range_filter でも動的カラムが使えるようになりました。

logical_range_filter は十分なレコードがマッチしたら検索をやめるため、マッチさせたい数が決まっている状況では、すべてのマッチするレコードを検索する logical_select よりも性能面でメリットがあります。

さいごに

7.0.8からの詳細な変更点は7.0.9リリース 2017-11-29を確認してください。

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

2017-10-29

Groonga 7.0.8リリース

今日は肉の日ですね!

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

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

変更内容

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

  • [Windows] クラッシュ時にバックトレースを表示するよう変更しました
  • QUERY_NO_SYNTAX_ERROR が効かないケースがあったのを修正しました
  • Ubuntu 17.10のサポート

[Windows] クラッシュ時にバックトレースを表示するよう変更しました

Windowsのみですが、クラッシュ時にバックトレースを表示するよう変更しました。 以下のようにどのように関数が呼び出されているかだけではなく、ソースファイル名と行数も出来る限り出力されるようにしているため、問題解決につながりやすくなります。

2017-10-29 16:27:02.371000|C| db.c:12352:0: 00000000657E9BD9: grn_table_sort(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.402000|C| window_function.c:374:0: 00000000659D08FB: grn_table_apply_window_function(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.434000|C| mrb_table.c:437:0: 00000000659EEFE0: mrb_grn_table_apply_window_function_raw(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.449000|C| ..\mruby-source\src\vm.c:1266:0: 0000000065A573BF: mrb_vm_exec(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.465000|C| ..\mruby-source\src\vm.c:821:19: 0000000065A59CA7: mrb_vm_run(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.481000|C| ..\mruby-source\src\vm.c:2619:0: 0000000065A5347C: mrb_run(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.481000|C| (unknown):-1:-1: 0000000065A5389D: mrb_funcall_with_block(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.496000|C| ..\mruby-source\src\vm.c:360:0: 0000000065A53CA9: mrb_funcall_with_block(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.512000|C| ..\mruby-source\src\vm.c:345:0: 0000000065A53E9F: mrb_funcall(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.543000|C| mrb_command.c:90:0: 00000000659E11FA: mrb_grn_command_run_wrapper(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.559000|C| command.c:199:0: 00000000657BA61C: grn_command_run(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.574000|C| expr.c:2635:0: 0000000065807B5B: grn_expr_exec(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.590000|C| ctx.c:1255:14: 00000000657BE8AC: grn_ctx_qe_exec(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.590000|C| ctx.c:1361:14: 00000000657BF36D: grn_ctx_send(): <libgroonga-0>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\libgroonga-0.dll>
2017-10-29 16:27:02.606000|C| groonga.c:402:0: 0000000000410A61: main(): <groonga>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\groonga.exe>
2017-10-29 16:27:02.606000|C| .\mingw-w64-crt\crt\crtexe.c:336:0: 00000000004013F8: __tmainCRTStartup(): <groonga>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\groonga.exe>
2017-10-29 16:27:02.606000|C| .\mingw-w64-crt\crt\crtexe.c:214:0: 000000000040151B: mainCRTStartup(): <groonga>: <c:\Users\groonga\groonga-7.0.8-x64-2017-10-29\bin\groonga.exe>
2017-10-29 16:27:02.606000|C| (unknown):-1:-1: 000000003B44168D: (unknown)(): <(unknown)>: <(unknown)>

QUERY_NO_SYNTAX_ERROR が効かないケースがあったのを修正しました

Groonga 7.0.6で入ったQUERY_NO_SYNTAX_ERRORを指定しているのにシンタックスエラーとなるケースがあったのを修正しました。以下のように、クエリーに単独で ( )(+) を指定した場合や~で始まる文字列を指定した場合に起こっていました。

select Names \
  --match_columns "_key" \
  --query "( )" \
  --query_flags ALLOW_PRAGMA|ALLOW_COLUMN|QUERY_NO_SYNTAX_ERROR

select Names \
  --match_columns "_key" \
  --query "(+)" \
  --query_flags ALLOW_PRAGMA|ALLOW_COLUMN|QUERY_NO_SYNTAX_ERROR

select Names \
  --match_columns "_key" \
  --query "~foo" \
  --query_flags ALLOW_PRAGMA|ALLOW_COLUMN|QUERY_NO_SYNTAX_ERROR

今回のリリースでは、上記のクエリーもエラーにならずに実行できるようになりました。

Ubuntu 17.10のサポート

今月19日にリリースされた Ubuntu 17.10 (Artful Aardvark)のサポートを始めました。

PPA経由でインストールできます。

さいごに

7.0.7からの詳細な変更点は7.0.8リリース 2017-10-29を確認してください。

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

2017-10-10

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

PostgreSQLで高速日本語全文検索をできるようにするPGroongaの2.0.2をリリースしました!メジャーバージョンアップです!

PGroongaについて

メジャーバージョンアップ後の最初のリリースアナウンスなので、PGroongaについての説明をします。今回の変更のハイライトはこの後にまとめています。

PGroongaはPostgreSQLを高速に日本語全文検索可能なシステムに拡張する魔法のような拡張機能です。PGroongaの他にも類似の拡張機能はありますが、速度・機能面で他の拡張機能とは一線を画しています。これはPGroongaはバックエンドにGroongaという本格的な全文検索エンジンを使っているためです。

速度

速度面では類似の拡張機能であるpg_bigmよりも高速です。PostgreSQL本体に含まれている全文検索モジュールtextsearchよりも高速です。インデックス作成時間、検索時間ともに数倍から10倍以上高速です。

まずはPGroongaとpg_bigmのインデックス作成時間です。Wikipedia日本語版データを使っています。

拡張機能 インデックス作成時間
PGroonga 約19分
pg_bigm 約33分

このケースでは2倍弱高速です。

続いてPGroongaとtextsearchのインデックス作成時間は次の通りです。textsearchが日本語非対応なのでWikipedia英語版データを使っています。データ量が違うので↑の結果とは直接比較はできません。

拡張機能 インデックス作成時間
PGroonga 約1時間24分
textsearch 約2時間53分

このケースでは2倍強高速です。

PGroongaとpg_bigmの検索時間は次の通りです。

検索語 ヒット数 PGroongaの検索時間 pg_bigmの検索時間
「PostgreSQL」または「MySQL」 約300 約2ms 約49ms
データベース 約1万5千 約49ms 約1300ms
テレビアニメ 約2万 約65ms 約2800ms
日本 約53万 約560ms 約480ms

「日本」で検索した場合はpg_bigmの方がやや速い(*1)ですがそれ以外の場合ではPGroongaの方が24倍から43倍ほど高速です。どのような検索語に対しても安定して高い性能を出していると言えます。

(*1) pg_bigmは3文字以上の検索語より2文字以下の検索語の方が得意です。

PGroongaとtextsearchの検索時間は次の通りです。

検索語 ヒット数 PGroongaの検索時間 textsearchの検索時間 Groongaの検索時間
「PostgreSQL」または「MySQL」 約1600 約6ms 約3ms 約3ms
database 約21万 約698ms 約602ms 約19ms
animation 約4万 約173ms 約1000ms(*2) 約6ms
America 約47万 約1300ms 約1200ms 約45ms

(*2) textsearchでは「animation」で約42万件(PGroongaの約10倍)ヒットしているため遅いです。要因は「animation」を「anim」とステミングしているからです。

PGroongaとtextsearchの検索時間はほぼ同じです。「animation」でtextsearchの方が遅いのはヒット数の違いからくるもので、本質的な検索速度の差ではありません。

参考までにPGroongaが使っている全文検索エンジンGroongaでの結果もつけています。Groongaではすべて数十msで検索できているので、PGroonga・textsearchの検索速度は、全文検索の速度ではなくPostgreSQL内の共通のオーバーヘッドの影響が大きいということがわかります。

ベンチマークの詳細は以下を参照してください。

機能面では他の類似拡張機能にはない次の機能を提供しています。

  • ノーマライズ機能
  • トークナイザーのカスタマイズ機能
  • トークンフィルターのカスタマイズ機能
  • クエリー言語を用いた検索
  • HTML対応のハイライト機能
  • HTML対応のスニペット機能
  • JSON検索
  • オートコンプリート機能
  • 類似文書検索機能
  • 同義語展開機能

ノーマライズ機能とは異なる表記のテキストを同等の表記のテキストに統一する処理です。

簡単なものでは「ポスグレ」というようにいわゆる半角カタカナで書かれたテキストも「ポスグレ」もどちらも「ポスグレ」というようにいわゆる全角カタカナに統一します。こうすることにより「ポスグレ」(全角カタカナ)で検索しても「ポスグレ」(半角カタカナ)で書かれたテキストでもヒットするようになります。

難しいものだと「㍊」は「ミリバール」に変換します。これらはUnicodeのNFKCという方法をベースにしています。

トークナイザーのカスタマイズ機能とは検索キーワードとなるキーワードを抽出する処理(トークナイズ処理)をカスタマイズできる機能です。抽出処理をカスタマイズすることにより、検索精度・検索性能のトレードオフをユーザーがコントロールできるようになります。

たとえば、「形態素解析器を使ったトークナイザー」というものにすれば精度・性能は向上しますが、検索漏れが発生することがあります。なお、他の類似拡張機能で形態素解析器を使ったトークナイズ処理をできるものはありません。PGroongaだけです。

「形態素解析器を使ったトークナイザー」にはMeCab(OSS)を使ったものとJMAT(非OSSの商用製品)を使ったものがあります。バックエンドで使っているGroongaはトークナイザーをプラグインとして追加できる機能を提供しているため様々なプロダクトを活用してトークナイザーを実装できるのです。

トークンフィルターのカスタマイズ機能とはトークナイザーで抽出したキーワードを加工する処理をカスタマイズできる機能です。textsearchではdictionaryという名前で同様の機能があります。PGroongaもtextsearchもステミング機能はこの仕組みで実現しています。

クエリー言語を用いた検索とは「A OR (B -C)」というようにAND/OR/NOT検索をユーザーが指定できる機能です。Googleと同様の文法で使えます。

HTML対応のハイライト機能とは検索キーワードを<span class="keyword">...</span>でマークアップする機能です。結果はそのままHTML内で使っても安全です。Webアプリケーションの開発に便利です。

HTML対応のスニペット機能とは検索キーワード周辺テキストを返す機能で、Googleの検索結果でも使われています。もちろん、キーワードは<span class="keyword">...</span>でマークアップされます。こちらも結果をそのままHTML内で使っても安全です。

JSON検索機能とはjsonb型のカラム全体をインデックスに登録し、柔軟に検索できる機能です。JSON内のすべてのテキストを全文検索することもできるため、JSON形式でいろんな構造のログを保存しておいて後で検索、といったことも簡単にできます。

オートコンプリート機能とは検索キーワードを入力するテキストボックスで入力キーワードを補完する機能です。Googleでも実装されている機能です。Googleと同様にローマ字で入力しても補完できます。

類似文書検索機能とは内容が似ているテキストを検索する機能です。ブログで類似記事を表示するために使えます。

同義語展開機能とは同じ意味だけど表現の違うキーワードをまとめて検索する機能です。たとえば「牛乳」と検索したときに「牛乳」も「ミルク」も検索します。

それぞれの機能が気になった人はPostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システムも見てください。

現在は未実装ですが、今後、提供予定の機能には次のような機能があります。これらはGroongaでは実装されている機能です。

  • 重み付け指定機能

使い方

PGroongaは全文検索のことをあまり知らなくても簡単に使えます。インデックスを作成してWHEREに条件を指定するだけです。

CREATE INDEX index_name ON table USING pgroonga (column);

SELECT * FROM table WHERE column &@~ '全文検索';

LIKEでもインデックスを使って検索できる機能を提供しているため、既存アプリケーションで次のように書いていたとしてもアプリケーションを変更せずに高速にできます。ただし、LIKEの方が全文検索専用の演算子&@~よりも遅いので、おいおいは専用の書き方に直していくことをオススメします。

SELECT * FROM table WHERE column LIKE '%全文検索%';

興味がでてきましたか?インストールしてチュートリアルを試してみてください。一通りの機能を確認できます。

インストールは簡単です。主要なプラットフォーム用にパッケージを提供しているからです。Windows用のバイナリーも提供しています。

ハイライト

今回のリリースの紹介に戻ります。

1.2.3以降のハイライトは次の通りです。

  • PostgreSQL 10のサポート

  • クエリーの実行プランの精度向上(高速化)

  • pgroongaスキーマの非推奨化

    • PGroonga 1系と後方互換性を維持しているため、従来通りpgroongaスキーマを使うこともできます。

それぞれ説明します。

PostgreSQL 10のサポート

先日リリースされたPostgreSQL 10に対応しています。最新のPostgreSQLでPGroongaを使えます!

PostgreSQL 10から導入されたロジカルレプリケーションにも対応しています。従来のフィジカルレプリケーションでもレプリケーションできましたが、PostgreSQL 10対応で新しい選択肢が増えたことになります。用途にあわせて使い分けてください。

従来のフィジカルレプリケーションを使うとディスク使用量が多いのですが、ある程度クラッシュリカバリーが効くようになります。

一方、ロジカルレプリケーションではより柔軟なスキーマ構成を実現できます。たとえば、マスターは更新専用にし、参照はスレーブだけで受付、PGroongaのインデックスはスレーブだけに作る(マスターには作らない)という構成もできます。こうすることで、更新性能を向上させつつ、参照に対してスケールアウトする構成にできます。

それぞれのレプリケーション方法についてベンチマークを実施する予定です。結果を楽しみにしていてください。

PostgreSQLクラスターの構成について商用サポートが必要な場合はPGroongaのサポートページを参照してください。

クエリーの実行プランの精度向上(高速化)

PostgreSQLのプランナーはPGroongaを含む各インデックスから情報を取得して処理コストを計算し、最適な実行プランを選択します。PGroongaがより精度の高い結果をプランナーに返せば、より高速な実行プランを選択できるようになります。

今回のリリースではSTABLEな関数(DBの内容によらず引数が同じなら結果が同じになる関数)・IMMUTABLEな関数(同一トランザクション内で引数が同じなら結果が同じになる関数)の結果を使って検索するときの実行プランの精度が向上しました。PGroongaで使うIMMUTABLEな関数の代表はpgroonga_query_expand()です。これはクエリー展開をする関数で、次のように検索クエリーに対して使います。このように検索クエリーを加工する関数を使ったときでもより高速な実行プランを選択しやすくなりました。

SELECT *
  FROM diaries
 WHERE content &@~ pgroonga_query_expand('synonyms', 'term', 'synonyms',
                                         'ユーザーが入力した検索クエリー');

pgroongaスキーマの非推奨化

PGroonga 1系ではpgroongaスキーマ以下に関数やオペレータークラスを定義していましたが、カレントスキーマ(多くの場合はpublic)以下にプレフィックス付きで定義した方が使いやすいという声が多かったです。そのため、PGroonga 2系ではpgroongaスキーマを非推奨とし、pgroonga_プレフィックス付きの名前で定義するようにしました。

pgroongaスキーマは非推奨となりましたが、後方互換性を維持するために従来通りpgroongaスキーマを使うこともできます。安心してアップグレードしてください。少なくともPGroonga 2系の間はpgroongaスキーマをサポートするので、徐々にpgroonga_プレフィックスを使った使い方に更新していってください。

アップグレード方法

1.0以降のすべてのバージョンと互換性があります。アップグレードの「互換性がある場合」用の手順でアップグレードしてください。

おしらせ

セッション

2017年11月3日(金、祝日)にPostgreSQL Conference Japan 2017PGroonga 2.0 - PostgreSQLでの全文検索の決定版というセッションがあります。

2017年12月5日(金)にPGConf.ASIA 2017PGroonga 2.0 – Make PostgreSQL rich full text search system backend!というセッションがあります。

どちらもPGroonga 2関連のセッションですが、PostgreSQL Conference Japan 2017の方がまだPGroongaを使っていない人向け、PGConf.ASIA 2017の方がPGroongaをすでに使っている人と拡張機能を開発している人向けの内容になります。

サポートサービス

PGroongaのサポートサービスを提供しています。インデックスや検索の設計方法に関するコンサルティングやトラブル時の調査、パフォーマンス改善・新機能追加などの技術支援など、PGroongaに関わるサポートが必要な場合はご相談ください。

まとめ

PGroongaの新しいリリースを紹介しました。PGroonga 2になって、よりPostgreSQLらしく使えるようになっています。

ここで紹介したもの以外の変更点はリリースノートを参照してください。

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

2017-09-29

Groonga 7.0.7リリース

今日は肉の日ですね!

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

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

変更内容

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

  • QUERY_NO_SYNTAX_ERROR が効かないケースがあったのを修正しました
  • command-version 3をデフォルトに設定できるようになりました
  • 関数を使っていてもselect結果をキャッシュするようになりました

QUERY_NO_SYNTAX_ERROR が効かないケースがあったのを修正しました

Groonga 7.0.6で入ったQUERY_NO_SYNTAX_ERRORを指定しているのにシンタックスエラーとなるケースがあったのを修正しました。以下のように、クエリーに単独で + を指定した場合に起こっていました。

select Names \
  --match_columns "_key" \
  --query "+" \
  --query_flags ALLOW_PRAGMA|ALLOW_COLUMN|QUERY_NO_SYNTAX_ERROR

今回のリリースでは、上記のクエリーもエラーにならずに実行できるようになりました。

command-version 3をデフォルトに設定できるようになりました

groongaコマンドの–default-command-version3 を指定できるようになりました。以前のバージョンでも --command_version 3 は成功していましたが、 --default-command-version 3 はエラーになっていました。

今回のリリースでは、--default-command-version 3を指定して起動できるようになっています。

関数を使っていてもselect結果をキャッシュするようになりました

selectコマンドで関数を使っていた場合、以前のバージョンではselect結果をキャッシュしていませんでしたが、今回のバージョンから条件付きでキャッシュするようになりました。 条件は、実行ごとに毎回結果が変わらないことです。変わってしまうのであればキャッシュしません。 したがって、 now()rand() は結果が変わるので従来どおり、キャッシュしません。そのほかの関数は同じクエリであれば結果が変わらないのでキャッシュされるようになりました。

Groongaをライブラリーとして使う人に向けに内部的な説明をすると、selectコマンドで使われているすべての関数の is_stable の値がtrue( GRN_TRUE )だった場合、select結果をキャッシュします。 is_stable の値はデフォルトでtrueになっています。引数が同じでも異なる結果を返す可能性のある関数を実装する場合、 is_stable にfalse( GRN_FALSE )を設定するようにしてください。なお、 now()rand()is_stable にはデフォルトでfalseが設定されているため、これらの関数が使われている場合はキャッシュしません。

is_stable を設定・参照するAPIとして、以下の2つを追加しました。

  • grn_proc_set_is_stable()
  • grn_proc_is_stable()

さいごに

7.0.6からの詳細な変更点は7.0.7リリース 2017-09-29を確認してください。

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

2017-08-29

Groonga 7.0.6リリース

今日は肉の日ですね!

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

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

変更内容

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

  • object_inspect コマンドを使ってディスク使用量を表示できるようになりました
  • クエリーをパースする際にフォールバックする機能をサポートしました
  • クエリー内の語のスコアを調整できるようになりました

object_inspect コマンドを使ってディスク使用量を表示できるようになりました

今回のリリースでは、object_inspect コマンドを使ってディスク使用量を表示できるようになりました。

これまでも、データベース全体のディスク容量はduコマンドなどを使えばわかります。しかし、特定のオブジェクト(例えば、テーブルだったり、インデックスなど)がどれくらいディスクを使用しているかというのは、簡単にはわかりませんでした。(できなくはないですが、オブジェクトと対応するパスを調べて突き合わせたりしないといけないので一手間かかります。)

今回のリリースからは、そのような面倒なことをしなくてもよくなりました。 object_inspect コマンドのレスポンスに disk_usage パラメータが含まれるようになっています。 使用量の確認には、そのパラメータを参照してください。単位はバイトです。

例えば、チュートリアルのサンプルで作ったデータベースのディスク使用量を調べてみましょう。

table_create --name Site --flags TABLE_HASH_KEY --key_type ShortText
column_create --table Site --name title --type ShortText
load --table Site
[
{"_key":"http://example.org/","title":"This is test record 1!"},
{"_key":"http://example.net/","title":"test record 2."},
{"_key":"http://example.com/","title":"test test record three."},
{"_key":"http://example.net/afr","title":"test record four."},
{"_key":"http://example.org/aba","title":"test test test record five."},
{"_key":"http://example.com/rab","title":"test test test test record six."},
{"_key":"http://example.net/atv","title":"test test test record seven."},
{"_key":"http://example.org/gat","title":"test test record eight."},
{"_key":"http://example.com/vdw","title":"test test record nine."},
]
table_create --name Terms --flags TABLE_PAT_KEY --key_type ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
column_create --table Terms --name blog_title --flags COLUMN_INDEX|WITH_POSITION --type Site --source title

Terms テーブルのディスク使用量を調べるには次のコマンドを実行します。

object_inspect --output_pretty yes Terms

すると次のような結果が得られます。

{
  "id": 258,
  "name": "Terms",
  "type": {
    "id": 49,
    "name": "table:pat_key"
  },
  "key": {
    "type": {
      "id": 14,
      "name": "ShortText",
      "type": {
        "id": 32,
        "name": "type"
      },
      "size": 4096
    },
    "total_size": 21,
    "max_total_size": 4294967294
  },
  "value": {
    "type": null
  },
  "n_records": 15,
  "disk_usage": 8437760
}

ディスク使用量は、"disk_usage": 8437760 であることがわかります。

今度はインデックスカラムのディスク使用量を調べてみましょう。 Terms テーブルの blog_title カラムのディスク使用量を調べるには次のコマンドを実行します。

object_inspect --output_pretty yes Terms.blog_title

すると次のような結果が得られます。

{
  "id": 259,
  "name": "blog_title",
  "table": {
    "id": 258,
    "name": "Terms",
    "type": {
      "id": 49,
      "name": "table:pat_key"
    },
  (省略)
  ],
  "disk_usage": 5283840
}

すると、ディスク使用量は、"disk_usage": 5283840 であることがわかります。

クエリーをパースする際にフォールバックする機能をサポートしました

今回のリリースでは、クエリーをパースする際にフォールバックする機能をサポートしました。 従来エラー扱いにしていたクエリーであってもエラーにはならなくなります。Groongaを使って開発しているアプリケーションで、ユーザーからの入力そのままに検索したいような場合に使うと便利です。

この機能を有効にするには、query_flagsQUERY_NO_SYNTAX_ERROR を指定します。

例えば、雑誌名のタイトルを検索するサンプルを考えてみます。

table_create --name Magazine --flags TABLE_HASH_KEY --key_type ShortText
column_create --table Magazine --name title --type ShortText
load --table Magazine
[
{"_key":"http://gihyo.jp/magazine/wdpress","title":"WEB+DB PRESS"},
{"_key":"http://gihyo.jp/magazine/SD","title":"Software Design"},
]
table_create --name Terms --flags TABLE_PAT_KEY --key_type ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
column_create --table Terms --name title --flags COLUMN_INDEX|WITH_POSITION --type Magazine --source title

このデータベースに対して、WEB + で検索してみましょう。

select Magazine --output_pretty yes --query 'WEB +' --match_columns title"

すると構文エラーとなります。

[
  [
    -63,
    1503902587.063566,
    0.0007965564727783203,
    "Syntax error: <WEB +||>",
    [
      [
        "yy_syntax_error",
        "grn_ecmascript.lemon",
        37
      ]
    ]
  ]
]

では、次は QUERY_NO_SYNTAX_ERROR をつけて実行してみましょう。

select Magazine --output_pretty yes --match_columns title --query 'WEB +'  --query_flags ALLOW_PRAGMA|ALLOW_COLUMN|QUERY_NO_SYNTAX_ERROR

すると次のようにエラーにならずに結果が得られます。

[
  [
    0,
    1503902343.382929,
    0.0419621467590332
  ],
  [
    [
      [
        1
      ],
      [
        [
          "_id",
          "UInt32"
        ],
        [
          "_key",
          "ShortText"
        ],
        [
          "title",
          "ShortText"
        ]
      ],
      [
        1,
        "http://gihyo.jp/magazine/wdpress",
        "WEB+DB PRESS"
      ]
    ]
  ]
]

QUERY_NO_SYNTAX_ERROR フラグをつけることで、WEB+ というキーワードとみなしてそれらが含まれるタイトルを検索する、という意味だと解釈します。そのため構文エラーにならないのです。

クエリー内の語のスコアを調整できるようになりました

今回のリリースでは、クエリー内の語のスコアを調整できるようになりました。

これまで、検索結果に対し、特定のカラムのスコアをあげて調整するということはできましたが、キーワード単位でスコアを上げたり、下げたりというというのはサポートしていませんでした。今回のリリースからはキーワード単位でスコアを微調整することが可能になります。

スコアの調整方法は次の3つがあります。

  • >
  • <
  • ~

例えば >GroongaGroonga のスコアをインクリメントします。<GroongaGroonga のスコアをデクリメントします。~Groonga は検索結果についてマッチしたドキュメントのスコアをデクリメントします。~ は検索結果そのものには影響しません。

実際にこれらスコアの調整方法を使ったサンプルを示します。

table_create --name Shops --flags TABLE_NO_KEY
column_create --table Shops --name keyword --type ShortText
load --table Shops
[
{"keyword":"居酒屋 洋食"},
{"keyword":"居酒屋 和食 "},
{"keyword":"居酒屋 中華"},
{"keyword":"カフェ 洋食"},
]

table_create --name Terms --flags TABLE_PAT_KEY --key_type ShortText --default_tokenizer TokenBigram --normalizer NormalizerAuto
column_create --table Terms --name keyword --flags COLUMN_INDEX|WITH_POSITION --type Shops --source keyword

このデータベースに対して、居酒屋 で検索してみましょう。

select Shops --output_pretty yes --match_columns keyword --output_columns keyword,_score --sort_keys -_score --query '居酒屋'

すると次のような結果が返ってきます。

[
  [
    [
      3
    ],
    [
      [
        "keyword",
        "ShortText"
      ],
      [
        "_score",
        "Int32"
      ]
    ],
    [
      "居酒屋 洋食",
      1
    ],
    [
      "居酒屋 中華",
      1
    ],
    [
      "居酒屋 和食",
      1
    ]
  ]
]

keyword に居酒屋を含むデータはすべてスコアが1になっています。

では、和食 が上位にくるように>を使ってスコアを調整してみましょう。

select Shops --output_pretty yes --match_columns keyword --output_columns keyword,_score --sort_keys -_score --query '居酒屋 (>和食 OR 洋食 OR 中華)'

[
  [
    [
      3
    ],
    [
      [
        "keyword",
        "ShortText"
      ],
      [
        "_score",
        "Int32"
      ]
    ],
    [
      "居酒屋 和食 ",
      8
    ],
    [
      "居酒屋 中華",
      2
    ],
    [
      "居酒屋 洋食",
      2
    ]
  ]
]

これで 和食 を含む場合にスコアが高くなりました。

今度は < を使って 洋食中華 よりもスコアをあげてみましょう。

select Shops --output_pretty yes --match_columns keyword --output_columns keyword,_score --sort_keys -_score --query '居酒屋 (>和食 OR <洋食 OR 中華)'

これで 洋食中華 よりも高いスコアとなりました。

[
  [
    [
      3
    ],
    [
      [
        "keyword",
        "ShortText"
      ],
      [
        "_score",
        "Int32"
      ]
    ],
    [
      "居酒屋 和食 ",
      8
    ],
    [
      "居酒屋 洋食",
      7
    ],
    [
      "居酒屋 中華",
      2
    ]
  ]
]

さいごに

7.0.5からの詳細な変更点は7.0.6リリース 2017-08-29を確認してください。

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