Programming log - Shindo200

イベント参加記録とプログラミング系の雑記

Rroonga で複数キーワードの AND 検索や OR 検索がしたい #2

2012年11月に『Rroonga で複数キーワードのAND検索,OR検索』という記事を書きました。今でもこの記事を見に来てくださる方がいるようです。ありがとうございます。当時は map とか inject を使うと短く書けて楽だと思ったのですが、後々に見直すと結構分かり難かったりしましたので、最近は別の書き方をしています。

AND 検索

(例題)
検索対象テーブル: Items
検索対象カラム : name, description
検索キーワード : Ruby, Perl
検索条件    : 両方の検索キーワードを含む(AND 検索)

require "groonga"

items = Groonga["Items"]
words = %w{Ruby Perl}

items.select do |item| 
  expression = nil

  words.each do |word|
    sub_expression = ((item.name =~ word) | (item.description =~ word))
    if expression.nil?
      expression = sub_expression
    else
      expression &= sub_expression
    end
  end

  expression
end

OR 検索

(例題)
検索対象テーブル: Items
検索対象カラム : name, description
検索キーワード : Ruby, Perl
検索条件    : どちらかの検索キーワードを含む(OR 検索)

require "groonga"

items = Groonga["Items"]
words = %w{Ruby Perl}

items.select do |item| 
  expression = nil

  words.each do |word|
    sub_expression = ((item.name =~ word) | (item.description =~ word))
    if expression.nil?
      expression = sub_expression
    else
      expression |= sub_expression
    end
  end

  expression
end

AND 検索、OR 検索を1つのメソッドにする

AND 検索と OR 検索のコードをよく見ていただくと分かるのですが、実は違いは一カ所だけです。
検索処理をメソッド化し、メソッドの引数で AND 検索か OR 検索かを指定できるようにしてみます。

require "groonga"

# キーワード words で items レコードを検索する
# operator に :and を指定したときは AND 検索
# operator に :or を指定したときは OR 検索
def search_item(words, operator)
  items = Groonga["Items"]

  items.select do |item| 
    expression = nil

    words.each do |word|
      sub_expression = ((item.name =~ word) | (item.description =~ word))
      if expression.nil?
        expression = sub_expression
      elsif operator == :and
        expression &= sub_expression
      elsif operator == :or
        expression |= sub_expression
      end
    end

    expression
  end
end

# AND 検索
search_item(%w{Ruby Perl}, :and)
# OR 検索
search_item(%w{Ruby Perl}, :or)

参考にすると良いプロダクト

新しいライブラリを使うときに、そのライブラリを使ったプロダクトのソースコードを読むとすごく勉強になります。ここでは、Rroonga を使ったプロダクトで有名なものを1つご紹介します。

Milkode
http://milkode.ongaeshi.me/
https://github.com/ongaeshi/milkode

Milkode は Rroonga を使ったソースコード検索アプリケーションです。Githubソースコードが公開されていますが、Rroonga の使い方を知りたい方は milkode / lib / milkode / database / 配下にあるコードを見ると勉強になると思います。