表題の通りですが、今まで運用していて全然気づかなかったことでした。
Elasticsearchにクエリを投げると、ヒットした際にレスポンスがめっちゃ長くてdevelopment.logが見づらくなってました。
ログをよく見ると、レスポンスからrecords
メソッドを呼ぶと、ヒットしたデータのIDの配列でデータベースから再取得していたので、「あれ?これってもしかしてElasticsearchからのレスポンスってIDだけでいいんじゃない?」と思ったので、早速実験してみました。
ちなみに、これがその処理。
elasticsearch-rails/active_record.rb at v7.1.1 · elastic/elasticsearch-rails · GitHub
elasticsearch-dslでクエリを組み立てる
Postモデルがあるとして、Elasticsearchに既にデータ登録されているとします。
elasticsearch-dslを使って、source
メソッドで取得フィールドを指定します。
definition = Elasticsearch::DSL::Search::Search.new definition.query do # 検索条件を設定 end # sourceメソッドで取得するフィールドを配列で指定する definition.source([:id]) # ElasticsearchでヒットしたデータのIDから、データベースに取りに行く posts = Post.__elasticsearch__.search(definition.to_hash).records
こうすると、ElasticsearchからのレスポンスはIDのみとなり、通信量が激減しました!😀はいえ、問題は、ちゃんとRailsで動くかどうかです。
テストの実行結果
担当プロジェクトのElasticsearch関連のテストを実行してみたのですが(見せられませんが…)、records
メソッドでデータベースデータを取得し直しているので、テストも全て通って問題なし!しかもElasticsearchのレスポンスが減ったからか、テストの速度も若干改善しました🚀
Elasticsearchからのレスポンス自体を活用するには?
あんまりちゃんと調べてないけど、たしかrecords
メソッドではなく、results
メソッドを使えばいいはず…。しかし、その際にはこの方法だとidしかないので、微妙です。でも、データベースへの問い合わせがないぶん、早いはず。ActiveRecordのモデルは使えないと思うけど。
elasticsearch-rails/response.rb at v7.1.1 · elastic/elasticsearch-rails · GitHub
画面で動作確認
本番環境と同等のマスタデータを搭載して、developmentモードで画面から検索をかけてみたところ、レスポンスが1秒近く改善しました。😯めちゃくちゃ効果あるやん…。1秒ではなかったです…。たまたま遅い時を引いてしまったぽかった。でもまぁ50ms〜150msくらい速くなりました。
まとめ
RailsでElasticsearchを使っている場合にrecords
メソッドを使っている場合は、Elasticsearchからのレスポンスはidだけあればいいので、idのみで取得しても問題なさそう。むしろ通信量が減って速度改善するしよさそう。