ref: master
plugins/elasticsearch/helpers/elasticsearch_helper.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
module ElasticsearchHelper def searchable_types { :all => _("All results"), :text_article => _("Articles"), :uploaded_file => _("Files"), :community => _("Communities"), :event => _("Events"), :person => _("People") } end def sort_types sorts = { :relevance => _("Relevance"), :lexical => _("Alphabetical"), :more_recent => _("More recent") } selected_type = (params[:selected_type] || nil) if selected_type and selected_type.to_sym != :all klass = selected_type.to_s.classify.constantize sorts.update klass.specific_sort if klass.respond_to? :specific_sort end sorts end def process_results selected_type = (params[:selected_type].presence|| :all).to_sym selected_type == :all ? search_from_all_models : search_from_model(selected_type) end private def search_from_all_models begin filter = (params[:filter] || "").to_sym query = get_query params[:query], sort_by: get_sort_by(filter), categories: params[:categories] Elasticsearch::Model.search(query,searchable_models, size: default_per_page(params[:per_page])).page(params[:page]).records rescue [] end end def search_from_model(model) begin klass = model.to_s.classify.constantize filter = (params[:filter] || "").to_sym query = get_query params[:query], klass: klass, sort_by: get_sort_by(filter ,klass), categories: params[:categories] klass.search(query, size: default_per_page(params[:per_page])).page(params[:page]).records rescue [] end end def default_per_page(per_page=nil) per_page || 10 end def get_sort_by(sort_by, klass=nil) case sort_by when :lexical {"name.raw" => {"order" => "asc"}} when :more_recent {"created_at" => {"order" => "desc"}} else (klass and klass.respond_to?(:get_sort_by)) ? klass.get_sort_by(sort_by) : nil end end def searchable_models searchable_types.except(:all).keys.map {|model| model.to_s.classify.constantize} end def query_string(expression="", models=[]) return { match_all: {} } if not expression { query_string: { query: "*"+expression.downcase.split.join('* *')+"*", fields: fields_from_models(models), tie_breaker: 0.4, minimum_should_match: "100%" } } end def query_method(expression="", models=[], categories=[]) query = {} current_user ||= nil query[:query] = { filtered: { query: query_string(expression, models), filter: { bool: {} } } } query[:query][:filtered][:filter][:bool] = { should: models.map {|model| model.filter(environment: @environment.id, user: current_user )} } unless categories.blank? query[:query][:filtered][:filter][:bool][:must] = models.first.filter_category(categories) end query end def get_query(text="", options={}) klass = options[:klass] sort_by = options[:sort_by] categories = (options[:categories] || "").split(",") categories = categories.map(&:to_i) models = (klass.nil?) ? searchable_models : [klass] query = query_method(text, models, categories) query[:sort] = sort_by if sort_by query end def fields_from_models(klasses) fields = Set.new klasses.each do |klass| klass::SEARCHABLE_FIELDS.map do |key, value| if value and value[:weight] fields.add "#{key}^#{value[:weight]}" else fields.add "#{key}" end end end fields.to_a end end |