class Elastify::Helpers::QueryBuilder

Attributes

filters[RW]
queries[RW]
scroll_size[RW]
scroll_timeout[RW]
sort[RW]

Public Class Methods

new(scroll_size: 15, scroll_timeout: '1m') click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 7
def initialize(scroll_size: 15, scroll_timeout: '1m')
    @queries = []
    @filters = []
    @sort = {}
    @scroll_size = scroll_size
    @scroll_timeout = scroll_timeout
end

Public Instance Methods

filter(*args) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 19
def filter(*args)
    must_filter(*args)
end
must_filter(fields, field_rules) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 23
def must_filter(fields, field_rules)
    @filters << { type: :must, field_rules: field_rules, fields: fields.instance_of?(Array) ? fields : [fields] }
end
scroll(scroll_size, scroll_timeout) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 35
def scroll(scroll_size, scroll_timeout)
    @scroll_size = scroll_size
    @scroll_timeout = scroll_timeout
end
search_term(fields, term) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 15
def search_term(fields, term)
    @queries << { term: term, fields: fields.instance_of?(Array) ? fields : [fields] }
end
should_filter(fields, field_rules) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 27
def should_filter(fields, field_rules)
    @filters << { type: :should, field_rules: field_rules, fields: fields.instance_of?(Array) ? fields : [fields] }
end
to_dsl() click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 48
def to_dsl
    max_scroll_size = 100; @scroll_size ||= 15
    @scroll_size = @scroll_size.to_i <= max_scroll_size ? @scroll_size : max_scroll_size
    if @sort.blank?
        @sort = @queries.blank? ? { id: { order: :desc } } : { _score: { order: :desc } }
    end
    dsl = { sort: @sort, size: @scroll_size, query: {} }
    if @queries.blank? and @filters.blank?
        dsl[:query][:match_all] = {}
        return dsl
    end
    dsl[:query] = { bool: { must: [], must_not: [], should: [] } }
    if @queries.present?
        dsl[:query][:bool][:must] += @queries.map do |query|
            { multi_match: { query: "#{query[:term].sanitize}", fields: query[:fields], operator: :and } }
        end
    end
    if @filters.present?
        @filters.select { |filter| filter[:type].equal?(:must) }.each do |filter|
            filter[:fields].each do |field|
                dsl[:query][:bool][:must] += map_has(field, filter[:field_rules][:has]) if filter[:field_rules][:has].present?
                dsl[:query][:bool][:must] << map_in(field, filter[:field_rules][:in]) if filter[:field_rules][:in].present?
                dsl[:query][:bool][:must_not] << map_in(field, filter[:field_rules][:not_in]) if filter[:field_rules][:not_in].present?
                dsl[:query][:bool][:must] << map_range(field, filter[:field_rules][:range]) if filter[:field_rules][:range].present?
            end
        end
        @filters.select { |filter| filter[:type].equal?(:should) }.each do |filter|
            filter[:fields].each_with_index do |field, index|
                dsl[:query][:bool][:should][index] ||= { bool: { must: [], must_not: [] } }
                dsl[:query][:bool][:should][index][:bool][:must] += map_has(field, filter[:field_rules][:has]) if filter[:field_rules][:has].present?
                dsl[:query][:bool][:should][index][:bool][:must] << map_in(field, filter[:field_rules][:in]) if filter[:field_rules][:in].present?
                dsl[:query][:bool][:should][index][:bool][:must_not] << map_in(field, filter[:field_rules][:not_in]) if filter[:field_rules][:not_in].present?
                dsl[:query][:bool][:should][index][:bool][:must] << map_range(field, filter[:field_rules][:range]) if filter[:field_rules][:range].present?
            end
        end
        dsl[:query][:bool][:minimum_number_should_match] = 1 if dsl[:query][:bool][:should].present?
    end
    return dsl
end

Private Instance Methods

map_has(field, data) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 89
def map_has(field, data)
    data.map { |value| { term: { field.to_s => value } } }
end
map_in(field, data) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 93
def map_in(field, data)
    { terms: { field.to_s => data } }
end
map_not_in(field, data) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 97
def map_not_in(field, data)
    { terms: { field.to_s => data } }
end
map_range(field, data) click to toggle source
# File lib/elastify/helpers/query_builder.rb, line 101
def map_range(field, data)
    { range: { field.to_s => { gte: data.first, lte: data.last, format: 'yyyy-MM-dd\'T\'HH:mm:ssZ' } } }
end