[groonga-dev,02071] Re: 複数の検索クエリがある場合のスニペットの取得対象について<Groonga>

Back to archive index

Kouhei Sutou kou****@clear*****
2014年 1月 24日 (金) 11:18:39 JST


須藤です。

実装してから連絡しようと思っていたのですが、なかなか実装して
いる時間がとれなかったので連絡します。

In <CANM+HheEVQukd7dQNkFVq2gQCPU_vHRQO****@mail*****>
  "[groonga-dev,02070] Re: 複数の検索クエリがある場合のスニペットの取得対象について<Groonga>" on Tue, 21 Jan 2014 08:08:11 +0900,
  Naoya Murakami <visio****@gmail*****> wrote:

>> grn_exprからキーワードを抽出するのを諦めて、自分でスニペット
>> 対象のキーワードを抽出するのがいいんじゃないかと思うんですよ
>> ねぇ。
>>
>>   --output_columns snippet_full(title,
>>                                 "html_escape"
>>                                 "keyword1", "<span class=\"keyword\">",
>> "</span>",
>>                                 "keyword2", "<span class=\"keyword\">",
>> "</span>")
>>
>> みたいな感じです。
>>
> 
> なるほど、これができたらアプリケーション側でハンドリングできますね!
> 見てみたら、Mroongaのudfの方は、こういう実装になっているんですね。

はい、そうです。
ただ、↑は引数が多くて使い勝手がよくないので、通常はあんまり
おすすめできないAPIだなぁと思っています。

Mroongaで実装してあるのは、Tritonnとの互換性のためです。
Tritonnでは↑のようなAPIで提供していたので、「まずは」同じも
のを提供しています。今後、もっと使い勝手がよいものを提供した
いなぁとは思っています。

> snippet_htmlでは、やはり英語文献がちょっとしんどいので、
> Mroongaのudfをまねて、Groongaのsnippet_full関数を作ってみました。
> 
> https://github.com/naoa/groonga/commit/af6ef72bf852e656239c8694c881ddd8ab71c015
> 
> Mroongaとほぼ同じ引数仕様で、Mroongaでは、照合順序を渡すところを
> この関数ではノーマライザ名にしています。

はい、それでよいと思います。

ノーマライザー名がわかっていれば、

  normalizer = grn_ctx_get(ctx,
                           GRN_TEXT_VALUE(normalizer_name),
                           GRN_TEXT_LEN(normalizer_name));

でノーマライザーオブジェクトを取得できます。

> フルスペックのスニペットの実装を期待してます。とりあえず、当面は、上のコードを
> パッチして、アプリケーション側を改修します。

Mroongaの場合はMySQLの構文の制限があるので、引数をずらずら並
べるのでよいと思っているのですが、GroongaはJavaScriptチック
な構文を採用しているので、

  snippet_full(text, {"option1": XXX, "option2": YYY, ...},
               KEYWORD1, KEYWORD1_OPEN_TAG, KEYWORD1_CLOSE_TAG,
               KEYWORD2, KEYWORD2_OPEN_TAG, KEYWORD2_CLOSE_TAG,
               ...)

みたいな使い勝手がいいんじゃないかと思っています。

で!そうすると、{"option1": XXX, "option2": YYY, ...}をパー
スしたら内部的にgrn_hashにする機能をいれないといけなくて、、、
みたいなところが現状です。。。

> おお!ノーマライザ名渡すために、既存の構造体とかAPIを変えないといけないの
> かなぁ、とか思ってましたが、セット用のAPIを追加すれば対応できるのですね!
> 期待してます!

grn_snip_set_normalizer()は実装しました。
あわせて、grn_expr_snip_add_conditions()というのも追加してい
ます。

grn_expr_snip()を使うと、grn_snipオブジェクトを作ってしまう
ので、ノーマライザーを変更するタイミングがなくなります。なの
で、grn_snip_open()した後に、grn_exprからキーワードを抽出で
きるようにしました。それが、grn_expr_snip_add_conditions()
です。これで、grn_exprからキーワードを抽出するときでもノーマ
ライザーを変更できます。

> これができれば、現状、抱えているスニペットにまつわる課題点はほぼ解消できます!

おぉ!

> 欲を言えば、スニペットがスカった場合、先頭のスニペットを取ってくれるような
> オプションがあれば、うれしいなとか思ったりします。

うーん、それをスニペット関数がやるのはやりすぎかなぁと思いま
した。フォールバックの挙動をどうするかってことですよね?それ
は、アプリケーション次第だとおもうんですよ。「先頭N文字をとっ
てきたい」ってことももちろんあると思いますが、「単に何も表示
しない」というのもありえますし、「スニペットはありません」と
表示するのもありえると思います。先頭N文字のNをスニペットとは
変えたいというのもあると思います。

そこまでスニペット関数の中に入れるのは出すぎている感じがしま
す。


そうではなく、snippet_html()は、何もスニペットがなかったとき
はnullを返すようにして(今は空の配列を返している)

  snippet_html(...) || "フォールバック時の値"

と書けるようにするのがいいと思いました。

こう書けるなら何もスニペットがないときはユーザーが制御できま
す。

ただ、今の「||」は「0」か「1」を返すようになっているので、こ
れをJavaScriptのように「最初に偽じゃなかったオブジェクト」を
返すようにする必要があります。で、これをやってから連絡しよう
と思ったのですが、まだ時間がとれていなくて未実装です。。。
今月のリリースには入れるつもりです。


-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

Groongaサポート:
  http://groonga.org/ja/support/
パッチ採用はじめました:
  http://www.clear-code.com/recruitment/
コミットへのコメントサービスはじめました:
  http://www.clear-code.com/services/commit-comment.html




groonga-dev メーリングリストの案内
Back to archive index