Rails
elasticsearch-rails
KOIL CSCDay 13

Elasticsearch with RoRで色んな検索をしてみる。その2

More than 1 year has passed since last update.

Elasticsearch with RoRで色んな検索をしてみる。その1の続きです。

今回は自分がハマった部分をサクサクっとご紹介します。
ちなみに体系的に記述する時間がないのと、現在Golangをやっている理由から
記述内容が微妙に異なる可能性がありますので
あらかじめご了承ください。

はじめに

せっかく全文検索エンジンをRailsで操作できるのに、
単なる全文検索だと楽にならない。。。
と思ったので、
分類分け方法をご紹介します。
ちなみに私がハマったのは、Elasticsearchの機能をRailsで書いた時の
構文エラーが主なものです。

前提

前回に引き続き以下のようなmodelを利用します。

$ cat ./app/models/concerns/xxx.rb
class Xxx < ApplicationRecord

  include Elasticsearch::Model

  index_name "es_#{Rails.env}"
  document_type 'test'

  [snip]

  def self.search(params = {})

    # ここに書いてく感じのやつです。

    # 検索クエリをなげて結果を表示
    __elasticsearch__.search(search_definition)
  end

一般的なグルーピング

元はこちらです。

xxx.levelというのがあるとして
こちらをGropingします。

### model
aggregation :level do
  terms field: 'level'
end

### view (haml)
= Xxx.Search.aggregations.level.buckets ### ハッシュが表示される。

リレーション先の値を表示する。

xxxに対して yyy がリレーションされている場合です。

### model
aggregation :yyy_group do
  terms field: 'yyy.group'
end

### view (haml)
= Xxx.Search.aggregations.yyy_group.buckets ### ハッシュが表示される。

ネストしてみる

xxx.levelに yyy.groupを配列的にくっつけます。
例えば、 level = [1,2,3]で yyy.group = ["group1", "group2"]と仮定した場合
出力結果が

{
 1 => {"group1" => 1, "group2" => 2},
 2 => {"group1" => 5, "group2" => 3},
 3 => {"group1" => 0, "group2" => 9},
}

のように表示されます。

aggregation :level do
  terms field: 'xxx.level' do
    aggregation :yyy_group do
      terms field: 'yyy.group'
    end
  end
end
### view (haml)
- Xxx.Search.aggregations.level.buckets do | level |
  level.aggregations.yyy_group.buckets ### ハッシュが表示される。

Stepしてみる。

ある値ごとにカテゴリーを作成したい場合は以下のような形でできます。

### model
price_step = 100
aggregation :price do
  range field: 'rates_from', ranges: [ { to:  price_step }, {  from:  price_step , to: price_step * 2}, {  from: price_step * 2, to: price_step * 4}, {from: price_step * 4 }]
end

### view
= Xxx.Search.aggregations.price.buckets

他にも色んな分け方ができますが、
長くだらだら記述しそうなので、一旦ここまでにします。