class PaperSearch < ActiveRecord::Base def to_definition options = {paper_type: paper_type, originator: originator, sort_by: sort_by} PaperSearch.definition(query, options) end def self.definition(q, options={}) Elasticsearch::DSL::Search.search do sort do if options[:sort_by] == 'score' by '_score' end by :published_at, order: 'desc' end query do # search query unless q.blank? multi_match do query q fields ["name", "content"] end else match_all end end # apply filter after aggregations post_filter do bool do must { term paper_type: options[:paper_type] } if options[:paper_type].present? must { term originator: options[:originator] } if options[:originator].present? # catchall when no filters set must { match_all } unless (options[:paper_type].present? || options[:originator].present?) end end aggregation :paper_types do # filter by originator f = Elasticsearch::DSL::Search::Filters::Bool.new f.must { match_all } f.must { term originator: options[:originator] } if options[:originator].present? filter f.to_hash do aggregation :paper_types do terms do field 'paper_type' end end end end aggregation :originators do # filter by paper_type f = Elasticsearch::DSL::Search::Filters::Bool.new f.must { match_all } f.must { term paper_type: options[:paper_type] } if options[:paper_type].present? filter f.to_hash do aggregation :originators do terms do field 'originator' end end end end end end end