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
他にも色んな分け方ができますが、
長くだらだら記述しそうなので、一旦ここまでにします。