Rroongaで全文検索する際には、Groonga::Table
クラスのselect
メソッドを使い、rubyの配列をselect
するような感覚で条件に一致するレコードを検索できる。
Groonga["Hoges"].select do |hoge|
hoge.title =~ /hello/
end
コードの表面上はArray#select
と同じように見えるが、裏側の動作原理は全く異なる。
Array#select
は配列の要素を1つ1つ走査して、それぞれの要素に対してブロックを呼び出して条件を満たすか否かを評価し、条件をみたす要素のみをピックアップする。
一方で、rroongaの場合はGroonga::Table#select
に渡されるブロックは一度しか実行されず、このブロックの実行によってGroongaの全文検索索引を使った問合せを構築し、Groongaのデータを検索する。
↑の例だと hoge.title
が Groonga::ColumnExpressionBuilder
のインスタンスになっており、=~
などの演算子が定義されていて、=~
が呼び出されると内部でGroonga用の問合せ式を構築する、という具合である。
ExpressionBuilder
で検索条件を作る
Groonga::Table#select
をブロック付きで呼び出す場合、ブロックのreturnする値はGroonga::ExpressionBuilder
でなければならない。
ExpressionBuilder
は、ExpressionBuilder
のサブクラスに対して何らかの演算子を適用することで得ることができる。基本的には、先の例のhoge.title
のようにカラム値を表す ColumnExpressionBuilder
を出発点として、値の一致・不一致であったり、大小比較などの演算子を適用して、最終的に評価したい条件に対応する ExpressionBuilder
を組み上げていく。
ExpressionBuilder
のインスタンスは、意味合いとしてはGroongaの検索に使われるgrn_expr(ぐるん式)に相当する。
RroongaでExpressionBuilder
を組み立てる際のポイントとしては、Rubyの文法の制限上、左辺値に ExpressionBuilder が来るように気をつけなければいけない点である。
例えば、Hoges
テーブルのtitle
カラムの値が"hage"
であるようなレコードを検索するときには
Groonga["Hoges"].select do |hoge|
hoge.title == "hage"
end
と書くことはできる一方で、
Groonga["Hoges"].select do |hoge|
"hage" == hoge.title
end
と書くことはできない。前者は ColumnExpressionBuilder
に対して ==
演算子を呼び出して、「カラム値が"hage"
である」というExpressionBuilder
を生成して返している。
一方後者は、"hage"
というString
に対して==
演算子を呼び出して、それがhoge.title
と等価であるかを比較し、Rubyの真偽値を返している。
同様に、hoge.number
という整数型のカラムがあったとして、「hoge.number
の値の2倍が10である」という条件で検索しようとする場合には
Groonga["Hoges"].select do |hoge|
(hoge.number * 2) == 10
end
とは書けるが、以下のようには書けない。
# 2 * hoge.number で error
Groonga["Hoges"].select do |hoge|
(2 * hoge.number) == 10
end
# 10 == (...) で error
Groonga["Hoges"].select do |hoge|
10 == (hoge.number * 2)
end
ExpressionBuilder
で使える演算子一覧
演算子 | 処理内容 |
---|---|
| | 論理和 |
& | 論理積 |
== | 等価比較 |
!= | 不等価比較 |
% | 数値の除算の剰余 |
* | 数値の積 |
+ | 数値の和 |
- | 数値の差 |
/ | 数値の除算の商 |
< | 大小比較(数値の大小、および文字列の辞書順(?)比較) |
<= | 大小比較 |
> | 大小比較 |
>= | 大小比較 |
=~ | 部分一致比較。右辺値が正規表現の場合には正規表現検索。 |
match(query) | Groongaのクエリ式を使った検索条件指定 |
prefix_search(prefix) | 前方一致検索 |
suffix_search(suffix) | 後方一致検索 |
similar_search(document) | 類似文書検索 |
term_extract(document) | 単語抽出検索 |