class CustomAttributes::SearchQuery
Builds a query in elastic search DSL
Attributes
customizable[RW]
defaults[RW]
field_list[RW]
filter_by[RW]
filter_by_delimiter[RW]
filter_or[RW]
filter_or_delimiter[RW]
match_any[RW]
page[RW]
per_page[RW]
query[RW]
sort_by[RW]
Public Instance Methods
build()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 8 def build { query: subquery, from: from, size: per_page, sort: sort_hash_to_array } end
default_fields()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 69 def default_fields default_fields = { custom_fields: Hash[customizable.available_custom_fields .select { |cf| cf.searchable == true } .map { |cf| [cf.slug.to_sym, {}] }] } if customizable.present? default_fields[:fields] = Hash[ customizable.class.default_fields.map { |f| [f.to_sym, {}] } ] end default_fields end
from()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 17 def from (page - 1) * per_page end
match_any?()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 65 def match_any? @match_any end
Private Instance Methods
collect_queries()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 112 def collect_queries # build field specific queries queries = model_field_queries + custom_value_queries # if there are not field specific queries, match all fields if queries.count.zero? if query == '*' { match_all: {} } else { match: { _all: query } } end else queries end end
custom_query_scaffold(query, field_slug, filter = false)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 239 def custom_query_scaffold(query, field_slug, filter = false) condition = { match: { 'custom_field_values.value' => query } } condition = { term: { 'custom_field_values.value.raw' => query } } if filter { nested: { path: 'custom_field_values', query: { bool: { must: [ condition, { term: { 'custom_field_values.custom_field_id' => resolve_custom_field_id(field_slug) } } ] } } } } end
custom_value_queries()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 128 def custom_value_queries return [] if filter_only_custom_fields(field_list).count.zero? filter_only_custom_fields(field_list).map do |field_slug, field| custom_query_scaffold(field.to_query_hash, field_slug) unless field.to_query_hash.empty? end.compact end
filter_hash_to_term_array(filter_list, delimiter = '')
click to toggle source
# File lib/custom_attributes/search_query.rb, line 172 def filter_hash_to_term_array(filter_list, delimiter = '') hash_to_array(filter_list) do |type, field_slug, field_data| field_data = field_data.split(delimiter).map(&:strip) if !delimiter.empty? && !field_data.is_a?(Array) if type == :custom_fields if field_data.is_a? Array field_data.map { |fd| custom_query_scaffold(fd, field_slug, true) } else custom_query_scaffold(field_data, field_slug, true) end else key = 'term' key = key.pluralize if field_data.is_a? Array { key.to_sym => { field_slug.to_s => field_data } } end end end
filter_only_custom_fields(fields)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 209 def filter_only_custom_fields(fields) return {} if fields[:custom_fields].nil? Hash[fields[:custom_fields].map { |k, v| [k, CustomAttributes::SearchQueryField.new(v, defaults)] }] end
filter_out_custom_fields(fields)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 203 def filter_out_custom_fields(fields) return {} if fields[:fields].nil? Hash[fields[:fields].map { |k, v| [k, CustomAttributes::SearchQueryField.new(v, defaults)] }] end
filter_term_array()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 191 def filter_term_array return filter_hash_to_term_array(filter_by) if filter_or.empty? filter_hash = { minimum_should_match: 1 } filter_hash[:must] = filter_hash_to_term_array(filter_by, filter_by_delimiter) unless filter_by.empty? filter_hash[:should] = filter_hash_to_term_array(filter_or, filter_or_delimiter) unless filter_or.empty? [{ bool: filter_hash }] end
find_custom_field_by_slug(field_slug)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 219 def find_custom_field_by_slug(field_slug) customizable.available_custom_fields.find { |cf| cf.slug == field_slug.to_s } || raise('Field not found') end
hash_to_array(field_list) { |type, field_slug, field_data| ... }
click to toggle source
# File lib/custom_attributes/search_query.rb, line 223 def hash_to_array(field_list) field_list.map do |type, fields| fields.map do |field_slug, field_data| yield(type, field_slug, field_data) end end.flatten.compact end
match_any_decorator(query_array)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 231 def match_any_decorator(query_array) if !match_any? { must: query_array } else { should: query_array, minimum_should_match: 1 } end end
model_field_queries()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 136 def model_field_queries return [] if filter_out_custom_fields(field_list).count.zero? queries = filter_out_custom_fields(field_list).map do |field_slug, field| { match: { field_slug => field.to_query_hash } } unless field.to_query_hash.empty? end.compact return [] if queries.empty? [{ bool: { should: queries, minimum_should_match: 1 } }] end
resolve_custom_field_id(field_slug)
click to toggle source
# File lib/custom_attributes/search_query.rb, line 215 def resolve_custom_field_id(field_slug) find_custom_field_by_slug(field_slug).try(:id) || raise('Field id not found') end
sort_hash_to_array()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 153 def sort_hash_to_array hash_to_array(sort_by) do |type, field_slug, field_data| if type == :custom_fields next unless find_custom_field_by_slug(field_slug).sortable { 'custom_field_values.value.raw' => { order: field_data || 'asc', nested_path: 'custom_field_values', nested_filter: { term: { 'custom_field_values.custom_field_id' => resolve_custom_field_id(field_slug) } } } } else { field_slug.to_s => { order: field_data } } end end end
subquery()
click to toggle source
# File lib/custom_attributes/search_query.rb, line 87 def subquery filter = filter_term_array + [{ term: { visible_in_search: true } }] # match all documents if no particular query isset if query == '*' && field_list.empty? return { bool: { must: [ { match_all: {} } ], filter: filter } } end { bool: { filter: filter }.merge(match_any_decorator(collect_queries)) } end