module Stretchie::Pants::ClassMethods

Public Instance Methods

Private Instance Methods

prepare_query(q_hash, options={}) click to toggle source

Prepare a query hash for ElasticSearch

# File lib/stretchie/pants.rb, line 156
def prepare_query(q_hash, options={})
  terms = options.fetch(:terms, {})
  limit = options.fetch(:limit, -1)
  skip  = options.fetch(:skip,  -1)
  order = options.fetch(:order, {})

  # Load the query but don't return any field data since we don't need it
  query = {
    'fields' => [],
    'query'  => q_hash
  }

  # If we have terms that must match (such as user_id) set them
  if terms.length > 0
    if q_hash.include?('term')
      q_hash['term'].merge! terms
    else
      if q_hash.include?('bool')
        if !q_hash['bool'].include?('must')
          q_hash['bool']['must'] = []
        end

        q_hash['bool']['must'] << {term: terms}
      else
        query['query'] = {
          'bool' => {
            'must' => [q_hash]
          }
        }

        query['query']['bool']['must'] << {term: terms}
      end
    end
  end

  # Set the limit
  if limit > 0
    query['size'] = limit
  end

  # Set the number of records to skip
  if skip > 0
    query['from'] = skip
  end

  # Set the sort order, sorting by _score last
  if !query.include? 'sort'
    query['sort'] = []
  end

  order.map do |k, v|
    query['sort'] << {k => v}
  end

  if query['sort'].select { |x| x.keys.first == '_score' }.count == 0
    query['sort'] << {'_score' => 'desc'}
  end

  query
end
run_query(query, options={}) click to toggle source

Run a query hash in ElasticSearch

# File lib/stretchie/pants.rb, line 112
def run_query(query, options={})
  query = prepare_query query, options

  # Run the query
  response = self.__elasticsearch__.search query

  Hashie::Mash.new({
    records: response.records,
    total_entries: response.results.total
  })
end
sanitize(q) click to toggle source

sanitize query string for Lucene. Useful if the original query raises an exception due to invalid DSL parse.

stackoverflow.com/questions/16205341/symbols-in-query-string-for-elasticsearch

@return self [Stretchie::QueryString] the modified QueryString.

# File lib/stretchie/pants.rb, line 132
def sanitize(q)
  # Escape special characters
  # http://lucene.apache.org/core/4_8_1/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#package_description#Escaping_Special_Characters
  escaped_characters = Regexp.escape('\\+-&|!(){}[]^~*?:\/')
  q = q.gsub(/([#{escaped_characters}])/, '\\\\\1')

  # AND, OR and NOT are used by lucene as logical operators. We need
  # to escape them
  ['AND', 'OR', 'NOT'].each do |word|
    escaped_word = word.split('').map {|char| "\\#{char}" }.join('')
    q = q.gsub(/\s*\b(#{word.upcase})\b\s*/, " #{escaped_word} ")
  end

  # Escape odd quotes
  if q.count('"') % 2 == 1
    q = q.gsub(/(.*)"(.*)/, '\1\"\2')
  end

  q
end