acts_as_ferret

昨日のコードの修正

$RAILS_ROOT/libの下にmecab_analyzer.rbとmecab_tokenizer.rbを置く方法ではUnit Testでは問題ないのだけど、Controllerから呼ぶとObject StateErrorとかいう例外があがってしまい、お手上げ。以下のように一つのファイルにまとめて解決。

require 'rubygems'
require 'MeCab'
require 'ferret'

class MecabAnalyzer < Ferret::Analysis::Analyzer
  include Ferret::Analysis

  def initialize(use_surface = false)
    @use_surface = use_surface
  end

  def token_stream(field, str)
    return MecabTokenizer.new(str, @use_surface)
  end
end

class MecabTokenizer < Ferret::Analysis::TokenStream
  include Ferret::Analysis

  def initialize(str, use_surface=false)
    @mecab = MeCab::Tagger.new
    self.text = str
    @use_surface = use_surface
  end

  def text=(str)
    @text = str
    @n = @mecab.parseToNode(text)
    @n = @n.next # skip EOS
    @pos = 0
  end

  attr_reader :text
  def next
    return nil if @n.stat == MeCab::MECAB_EOS_NODE
    features = @n.feature.split(/,/)
    t = @use_surface ? @n.surface : features[6]
    token = Ferret::Analysis::Token.new(t, @pos, @pos+@n.rlength)
    @pos += @n.rlength
    @n = @n.next

    return token
  end
end

MacLinuxとで結果が異なる

なんかMacだと常に全件がスコア1.0でヒットしてしまう。mecab-ruby周りかなー。