I used filtering query to solve this problem, first created ActiveSupport::Concern called searchable.rb , the problem is as follows:
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
I have the following problem in the models/concerns directory. In movies.rb , I have:
class Movie < ActiveRecord::Base include Searchable end
In movies_controller.rb I search in the index action, and the action looks like this:
def index options = { actor: params[:taxon], sort: params[:sort] } @movies = Movie.search(params[q], options).records end
Now, when I go to http://localhost:3000/movies?q=future&actor=Christopher , I get all the records that have the word future by their name, and there is an actor named Christopher. You can have several filters, as shown in the expert template, examples of application templates found here .