Octopress/JekyllでGroongaによる類似文書検索機能を使う

Groonga 2.0.2から類似文書検索機能が使えるようになった。GroongaのRubyバインディングであるRroongaでは2.0.3で同機能への対応がなされている。

Groongaレベルではselect ... --filter カラム名 *S "テキスト"により類似文書検索ができる。このときに指定するカラムは全文検索できるようインデックスを作っておかなければならない。

Rroongaからの使い方は以下のようになる。(Article.bodyに抽出対象のテキストがあるとする。)

records = Groonga['Article'].select do |record|
  record.body.similar_search(article_body)
end

records.sort([
      {key: '_score', order: 'descending'},
    ], limit: 10).each do |record|
  ... # 見付かった文書を使った処理
end

この機能をJekyllやOctopressから利用できるようにしてみた。試行錯誤の様子が残っているけどgistに置いておいた。

Gemfileにgem 'rroonga', '>= 2.0.3'を加えること。また、この中ではMecabを使っているのでMecabを有効にしたGroongaを構築するか、Mecabを使わないようにすること。

Octopressならsource/_layouts/post.htmlに以下を加えるなどすれば類似文書へのリンクを表示できる。

{{"{"}}% if page.similar_posts.size > 0 %}
  <p class="meta">Similar posts:
    {{"{"}}% for sp in page.similar_posts limit: 5 %}
      <span class="similar-post"><a href="{{"{{"}} root_url }}{{"{{"}} sp.url }}">{{"{{"}} sp.title }}</a></span>
    {{"{"}}% endfor %}

{{"{"}}% endif %}

なお、Jekyllには類似文書検索をするための機能がもとからあって、--lsiオプションにより利用できる。ただ、手元の環境ではこれがうまく動かなった。0割り算エラーが発生したりしてしまって手に負えそうにないため、上のGroongaを利用する方法を考えた。