Hiroaki Nakamura
hnaka****@gmail*****
2015年 8月 11日 (火) 18:06:50 JST
こんにちは、中村です。 PGroongaでPostgreSQLの関数としてpgroonga.snippet_htmlを作りたいと 思っているのですが、実装方法について相談させください。 Groongaには実験的な機能ですがsnippet_html()という関数が存在しています。 http://groonga.org/ja/docs/reference/functions/snippet_html.html ですが、理想としてはPostgreSQLの関数としてpgroonga.snippet_html()を作りたいと 考えています。というのはcontentというカラムに検索対象のテキストが入っている時に select * from テーブル名 where content @@ 'クエリー' というSQLで検索するとcontentカラムのデータサイズが大きい時に、データ転送量が 肥大化してしまうからです。今扱っているデータには数百MBぐらいのものがあるので 丸ごと転送したくないのです。 もし以下のようなSQLを書ければcontentの値全体の転送は不要でsnippet_htmlの 加工結果の小さいサイズの転送だけですみます。 select id, title, snippet_html(content, 他に必要な引数...) as content from テーブル名 where content @@ 'クエリー' とりあえず、PGroongaのコードを見ながら、見よう見まねでクイック&ダーティーな実装を作ってみました。 https://github.com/pgroonga/pgroonga/compare/master...hnakamur:add_pgroonga_snippet_html https://github.com/pgroonga/pgroonga の「基本的な使い方」のテーブルとデータがある 状態で、以下のSQLを実行すればデータが取得できるようになりました。 test=# select id, json_extract_path_text(pgroonga.snippet_html(memos, 'groonga', 'memos_index', 'content')::json, '1', '0', '2', '0', '0') from memos where content %% 'groonga'; id | json_extract_path_text ----+------------------------------------------------------------------------------------------------------------------------------------- 2 | <span class="keyword">Groonga</span>は日本語対応の高速な全文検索エンジンです。 3 | P<span class="keyword">Groonga</span>はインデックスとして<span class="keyword">Groonga</span>を使うためのPostgreSQLの拡張機能です。 4 | <span class="keyword">groonga</span>コマンドがあります。 (3 rows) しかし、%%の代わりに@@を使うとなぜか0件になってしまうという問題があります。 test=# select id, json_extract_path_text(pgroonga.snippet_html(memos, 'groonga', 'memos_index', 'content')::json, '1', '0', '2', '0', '0') from memos where content @@ 'groonga'; id | json_extract_path_text ----+------------------------ (0 rows) いずれにせよ、現状の実装は https://github.com/hnakamur/pgroonga/blob/f3c284b2643285f002c2b67e5929d139cc558763/pgroonga.c#L1363-L1378 でpgroonga.command()と同等の処理を行うという手抜き実装なので、GroongaのCのAPIを使って書きなおすべきかと 思っております。 SQL関数としてのpgroonga.snippet_htmlの引数は https://github.com/pgroonga/pgroonga/blob/870f0edae912a53e3bb2f232e7e82d7c857d117e/pgroonga.sql#L26-L31 にあるように 1. "row" record 2. query text 3. indexName cstring 4. columnName cstring と4つもあります。 rowはctidを取得するために必要です。 queryとindexNameとcolumnNameはGroongaのクエリの作成と検索結果の値の取得に必要です。 本当はSQLのwhere句で同じクエリを作っているので、それを参照したいところです。 が、SQLの関数から参照する方法が見つけられないので、Groongaのクエリ作成に必要な情報を 引数で渡して行ごとにクエリを作っています。 PGroongaのソースもPostgreSQLのソースも読み始めたばかりなので、もっと良い方法がありそうな 気はしています。 ということで、仕様や実装についてアドバイスやご意見ありましたら、ぜひフィードバックを お願いします。 -- 中村 弘輝 )Hiroaki Nakamura) -------------- next part -------------- HTML$B$NE:IU%U%!%$%k$rJ]4I$7$^$7$?(B... 다운로드