ElasticSearch(rails)で階層化されたドキュメントの複数フィールドをまとめてAND検索する方法

  • 1
    Like
  • 0
    Comment

elasticsearch-rails を導入して単純な検索までは簡単に実装できたのですが、階層化されたドキュメントのAND検索をする方法がなかなかでてこなかったのでメモ。

class Article
  include Elasticsearch::Model

  belongs_to :genre

  # こんな感じで階層化されたドキュメントが登録されるようにする
  def as_indexed_json(options = {})
    as_json(
      only: [:title, :content],
      include: {
        genre: {only: :name}
    })
  end

  # 各フィールドをまたいでAND検索
  def multi_field_search
    query = {query:
               {
                 multi_match: {
                   query: query,
                   type: 'cross_fields',
                   fields: %w[title content genre.name],
                   operator: 'and'
                 }
               }
    }
    Article.search(query).records
  end
end

ポイントは以下の2つ

  • multi_matchを使う
  • type に 'cross_fields' を指定する

multi_matchでfieldsに複数のフィールドを指定することができるようになります。fieldsパラメータではgenre.nameのようにドット区切りにして下層のフィールドを指定できます。

これだけですと、AND検索が単一フィールド内でしか行われないため、複数のワードが別々のフィールドに格納されているとマッチしません。そこでtypecross_fieldsを設定すると、フィールドをまたいでAND検索できるようになります。