[groonga-dev,00471] Re: referenceでの検索

Back to archive index

Kouhei Sutou kou****@clear*****
2011年 3月 30日 (水) 22:52:23 JST


須藤です。

In <4d279c40-2773-3091-9817-697a927982b3 @ api104>
  "[groonga-dev,00470] referenceでの検索" on Wed, 30 Mar 2011 08:52:30 +0900,
  "Endo Akira" <endo4****@goo*****> wrote:

> p items.select{|r|
>   res = false
>   r.pisrefs.each{|p|       #######
>     res |= p.jan =~ '123'
>   }
>   res
> }
> 
> 以上、itemsテーブルにpisテーブルへのreferenceをvectorでいれた
> つもりですが、#######のところで、
> undefined method 'each' for #<Groonga::ExpressionBuildable::ColumnValueExpressionBuilder:0x000000029e8868
> というエラーが出ます。selectの中では、挙動が変わるようで、ここから進めません。

なるほど。
selectの中(ブロック)はたしかに他のRubyの部分とは意味合いが
異なるのです。

解説の前に、これが期待する動作かなぁというコードを示しておき
ます。

  result = items.select{|r|
    r.pisrefs.jan =~ "123"
  }
  result.each do |record|
    p record.key.pisrefs.collect(&:jan)
  end


以下、解説です。

selectのブロックは「grn式(ぐるんしき)」というgroongaの式オブジェ
クトを生成するもので、

  各レコード毎にブロックを評価してマッチするレコードを特定する

ということはしていません。

例えば、Arrayのselectでは

  > [1, 2, 3].select {|n| p n; n.odd?}
  1
  2
  3
  => [1, 3]

となり、各要素に対してブロックを評価して目的の要素だけを返し
ます。

しかし、テーブルのselectでは、

  > items.select {|record| p record; record.content =~ "キーワード"}
  <Groonga::RecordExpressionBuilder:...>
  => #<Groonga::Hash ...> # ← 「キーワード」にマッチする
                          #     レコードがたくさんあるとする。

というようにブロックは常に1度しか評価されません。


これは、Rubyからgroongaを使ってもできるだけgroongaの速度を落
とさないようにするためです。すべてのレコードに対してRubyのブ
ロックを評価していてはせっかくのgroongaの速度が殺されてしまう
のです。Rubyのブロックを1度だけ評価して、groongaの式オブジェ
クト(grn式)にし、後はgroongaが内部で検索を実行することによ
り、groongaの速度とRubyの使いやすさを両立するようにしています。


で、問題はどうやってのぞみのgrn式を作るかですが、うーん、そ
うですねぇ。すぐには説明できないです。。。すみません。。。

ざっくりというと、こんな感じなのですが。。。

  * 条件式(真偽値を返す(Rubyの)式)を書く

    例:
      record.name == "太郎"
      record.name =~ "キーワード"

  * eachを使わない(eachは使えない)

    例:
      record.names.each do |name|
        name ...
      end

  * 条件式を連結する

    例:
      # 東京に住んでいる太郎さんを検索
      (record.name == "太郎") & (record.address =~ "東京")
      # 東京か大阪に住んでい人を検索
      (record.address =~ "東京") | (record.address =~ "大阪")


残念ですがまとめられないので、わからないことはここで聞いても
らえるといいかと思います!


-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

プログラミングが好きなソフトウェア開発者を募集中:
  http://www.clear-code.com/recruitment/




groonga-dev メーリングリストの案内
Back to archive index