Programming log - Shindo200

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

Rroonga で複数キーワードのAND検索,OR検索

■ 2014年2月12日追記

2012年11月当時はこの記事に掲載されている書き方で AND 検索、OR 検索を実装したのですが、後々に見直すと分かり難かったりしましたので、最近は別の書き方をしています。詳しくは下記のURLの記事を見てください。

http://shindolog.hatenablog.com/entry/2014/02/12/011935


 

Rroonga は Ruby らしい書き方で groonga を使うことができるライブラリです。


Rroonga
http://ranguba.org/rroonga/ja/

最近利用しているのですが、使い方をまとめたドキュメントがまだまだ少ない感じがあります。僕が利用して最初に嵌ったことは、複数キーワードのAND条件での検索、OR条件での検索の書き方です。方法はいくつかあるのですが、良さそうだと思った書き方を記録しておきます。

・AND条件での検索
そもそも検索には
select(options) {|record| ... }
select(query, options)
select(expression, options)
の3つの書き方があります。今回は select(options) {|record| ... } を使って、Items テーブルのname カラムと description カラムのどちらかに「Ruby」「Perl」の両方を含む検索を行うコードを書いてみます。

require 'groonga'
def and_search_word
  items = Groonga["Items"]
  words = ["Ruby", "Perl"]
  items.select do |item|
    words.map do |word|
      (item.name =~ word) |
      (item.description =~ word)
    end
  end
end


select メソッドのブロックの中は、grn式というGroonga特有の式で評価して、検索条件とマッチしたレコードを返すようになっています。AND条件での検索の場合は & を、OR条件での検索の場合は | を使います。Rubyの論理演算子である && や || を使っても、期待したレコードは返ってきません。また、& の代わりに
[A, B] というように配列を使って書くと、A と B でAND条件での検索になります。ここでは「name カラムか description カラムのどちらかに "Ruby" を含む」「name カラムか descriotion カラムのどちらかに "Perl" を含む」の2つの要素が入った配列を作り、AND条件で検索を行うようにしています。


・OR条件での検索
Items テーブルの name カラムと description カラムのどちらかに「Ruby」「Perl」のどちらかを含む検索を行うコードを書いてみます。

require 'groonga'
def or_search_word
  items = Groonga["Items"]
  words = ["Ruby", "Perl"]
  items.select do |item|
    words.inject(item) do |result_item, word|
      result_item |
      (item.name =~ word) |
      (item.description =~ word)
    end
  end
end


「name カラムに "Ruby" を含む」「description カラムに "Ruby" を含む」「name カラムに "Perl" を含む」「description カラムに "Perl" を含む」の4つ要素を | で繋げれば、OR条件での検索になります。ここでは inject メソッドを使って4つの要素を | で繋げるようにしています。OR条件での検索の書き方は悩みましたが、これが見やすいのかなと思いました。