私はfiltering query
これを解決するために使用しました。最初にActiveSupport::Concern
呼び出されたを作成しましたsearchable.rb
。懸念は次のようになります。
module Searchable
extend ActiveSupport::Concern
included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks
index_name [Rails.application.engine_name, Rails.env].join('_')
settings index: { number_of_shards: 3, number_of_replicas: 0} do
mapping do
indexes :title, type: 'multi_field' do
indexes :title, analyzer: 'snowball'
indexes :tokenized, analyzer: 'simple'
end
indexes :actors, analyzer: 'keyword'
end
def as_indexed_json(options={})
hash = self.as_json()
hash['actors'] = self.actors.map(&:name)
hash
end
def self.search(query, options={})
__set_filters = lambda do |key, f|
@search_definition[:post_filter][:and] ||= []
@search_definition[:post_filter][:and] |= [f]
end
@search_definition = {
query: {},
highlight: {
pre_tags: ['<em class="label label-highlight">'],
post_tags: ['</em>'],
fields: {
title: {number_of_fragments: 0}
}
},
post_filter: {},
aggregations: {
actors: {
filter: {bool: {must: [match_all: {}]}},
aggregations: {actors: {terms: {field: 'actors'}}}
}
}
}
unless query.blank?
@search_definition[:query] = {
bool: {
should: [
{
multi_match: {
query: query,
fields: ['title^10'],
operator: 'and'
}
}
]
}
}
else
@search_definition[:query] = { match_all: {} }
@search_definition[:sort] = {created_at: 'desc'}
end
if options[:actor]
f = {term: { actors: options[:taxon]}}
end
if options[:sort]
@search_definition[:sort] = { options[:sort] => 'desc'}
@search_definition[:track_scores] = true
end
__elasticsearch__.search(@search_definition)
end
end
end
models/concerns
ディレクトリに上記の懸念があります。私movies.rb
が持っている:
class Movie < ActiveRecord::Base
include Searchable
end
movies_controller.rb
私はアクションを検索していますが、index
アクションは次のようになります。
def index
options = {
actor: params[:taxon],
sort: params[:sort]
}
@movies = Movie.search(params[q], options).records
end
ここで にアクセスするhttp://localhost:3000/movies?q=future&actor=Christopher
と、タイトルに「未来」という単語があり、クリストファーという名前の俳優がいるすべてのレコードが表示されます。ここexpert
にあるサンプル アプリケーション テンプレートのテンプレートに示されているように、複数のフィルターを使用できます。