前回の記事では、Ruby on RailsとElasticsearchで全文検索機能を実装しました。 同じ構成で、今回はMore Like This APIによる関連記事の実装を行ないます。

Elasticsearchでは、クエリを実行した際、ヒットしたドキュメントにスコアが設定されます。 スコアは「クエリ対してどれくらい関連しているか」を表す数値で、これをもとに関連記事を実現できます。

これも全文検索とおなじようにAPIを叩くだけでできます。 それでは実装を見ていきます。

要件

前回に引き続き、Articleモデルについて考えます。 モデルのインスタンスそれぞれがtitlecontentを持っていますが、この値に関連する記事を取得するためのメソッドを実装します。

実装

前回実装したArticleモデルのインスタンスメソッドとして、次のような#more_like_thisメソッドを生やします。

次のように、More Like This APIに:idsを渡すことで、それに関連するドキュメントを取得できます。 ここでは当該インスタンスのtitlecontentについて関連するドキュメントを取得しています。

def more_like_this
  self.class.__elasticsearch__.search({
    query: {
      more_like_this: {
        fields: %w(title content),
        ids: [id],
        min_doc_freq: 0,
        min_term_freq: 0
      }
    }
  })
end

:min_doc_freq:min_term_freqは、当該レコードと関連の低いドキュメントをフィルタリングするための設定です。 このあたりのパラメータのチューニングについては要件に変わってくると思いますので、詳細は公式ドキュメントをご覧ください。

実行例

上記の#more_like_thisメソッドの実行例を次に示します。 このように、タイトルに関連した記事を取得できているのが分かります。

> article = Article.find(4)
> article.title
=> "Docker ComposeでRuby+PostgreSQLによるRails開発環境を構築する方法"
>
> article.more_like_this.results.map(&:title)
=> ["Docker入門:Dockerとは?イメージやコンテナについて、インストール方法など", "RailsでRedisのSortedset型によるリアルタイムランキングを実装する方法", "MacでPHPの開発環境を構築する。XAMPPのインストールや起動方法、おすすめの設定など", "DockerでRedisサーバを起動してRailsアプリから接続する方法", "JavaScriptの新しいパッケージマネージャYarnとは?npmとの違いやインストール方法など", ...]

参考記事

おわりに

4回に分けてElasticsearchの基礎から開発環境の構築方法、Ruby on Railsによる機能の実装方法について書いてきました。

実際の開発では公式ドキュメントや文献などを読む必要があるとして、基本的な開発の流れは本連載で抑えられたかと思います。 Elasticsearch開発の際の参考になれば幸いです。