module Elasticsearch::Search::ClassMethods

Public Class Methods

do_elasticsearch_for_ios(q, type, from) click to toggle source
# File app/models/elasticsearch/search.rb, line 149
def self.do_elasticsearch_for_ios(q, type, from)
  qs=full_query(q, nil, from, nil, 15)
  # Elasticsearch::Base::log "QUERY STRING: #{qs.inspect}"
  begin
    uri=(URI.parse("#{ELASTICSEARCH_URI}/#{type}/_search?pretty=true"))
    Net::HTTP.start(uri.host, uri.port) do |http|
      headers = { 'Content-Type' => 'application/json'}
      data = qs.to_json
      response = http.send_request("GET", uri.request_uri, data, headers)
      # Elasticsearch::Base::log "ElasticSearch#search response: #{response.code} #{response.message} #{response.body}"
      # Elasticsearch::Base::log "ElasticSearch#search response: #{response.code} #{response.message}"
      @code=response.code
      @body=response.body
    end  
  rescue => e
    Elasticsearch::Base::log "ElasticSearch#search ERROR #{e}"
    return []
  end    

  if @code.eql?('200')
    results=Hash.new
    results['hits']=[]
    
    results['total_hits'] = JSON.parse(@body)['hits']['total']
    JSON.parse(@body)["hits"]["hits"].each do |result|
      # Elasticsearch::Base::log "### #{result['_type']}, #{result['_id']}, score #{result['_score']} "
      item=result['_type'].classify.constantize.find_by_id(result["_id"])
      results['hits'].push(item) if item.present?
    end
  else
    return []
  end
  results
end

Public Instance Methods

do_elasticsearch_with_facets(q, filters, from, sort=nil, only_title=false) click to toggle source
# File app/models/elasticsearch/search.rb, line 84
def do_elasticsearch_with_facets(q, filters, from, sort=nil, only_title=false)
  qs=full_query(q, filters, from, sort, only_title)
  # Elasticsearch::Base::log "QUERY STRING: #{qs.inspect}"
  es_uri = ELASTICSEARCH_URI
  if defined?(ELASTICSEARCH_BOPV_URI)
    es_uri << ",#{ELASTICSEARCH_BOPV_URI.split('/').last}"
  end
  begin
    uri=(URI.parse("#{es_uri}/_search?pretty=true"))
    Net::HTTP.start(uri.host, uri.port) do |http|
      headers = { 'Content-Type' => 'capplication/json'}
      data = qs.to_json
      response = http.send_request("GET", uri.request_uri, data, headers)
       # Elasticsearch::Base::log "ElasticSearch#search response: #{response.code} #{response.message} #{response.body}"
      Elasticsearch::Base::log "ElasticSearch#search response: #{response.code} #{response.message}"
      @code=response.code
      @body=response.body
    end  
  rescue => e
    Elasticsearch::Base::log "ElasticSearch#search ERROR #{e}"
    return []
  end    
  if @code.eql?('200')
    results=Hash.new
    results['hits']=[]
    
    results['total_hits'] = JSON.parse(@body)['hits']['total']
    JSON.parse(@body)["hits"]["hits"].each do |result| 
      # Elasticsearch::Base::log "### #{result['_type']}, #{result['_id']}, score #{result['_score']}"
      item=result['_type'].classify.constantize.find_by_id(result["_id"])
      if item.present?
        item.score = result['_score']
        item.explanation = result['_explanation']
        results['hits'].push(item)
      end  
    end
    
    results['facets']=Hash.new
    facets_body=JSON.parse(@body)['facets']
    # Facets
    Elasticsearch::Base::FACETS.keys.each do |att|
      if att.eql?('date')
        terms='ranges'
      else
        terms='terms'
      end
      results['facets'][att]=[]
      facets_body[att][terms].each do |facet|
        unless facet['count'].zero?
          case att
          when 'date'
            value=Elasticsearch::Base::DATE_IN_HOURS[((facet['from'] - facet['to']).to_i.abs/3600000)]
          else
            value=facet['term']  
          end    
          results['facets'][att].push([value, facet['count']])
        end  
      end  
    end
  else
    return []
  end
  results
end
facets() click to toggle source
# File app/models/elasticsearch/search.rb, line 66
def facets
  fh = Hash.new
  Elasticsearch::Base::FACETS.each_pair do |facet, att|
    value = {'field' => att[:field], 'size' => att[:size]}
    value.merge!(att[:other]) if att[:other].present?
    fh[facet] = { att[:type] => value }
  end  
  fh  
end
filters(filters) click to toggle source
# File app/models/elasticsearch/search.rb, line 53
def filters(filters)
  f=[]
  filters.each do |term|
    case term[0]
    when 'date'
      f << {'range' => {'published_at' => Elasticsearch::Base::DATE_RANGES[term[1]]}}
    else  
      f << {'term' => {term[0] => term[1] } }
    end  
  end  
  {'filter' => { 'and' => f }}
end
full_query(q, filters, from=0, sort=nil, only_title=false, size = Elasticsearch::Base::ITEMS_PER_PAGE) click to toggle source
# File app/models/elasticsearch/search.rb, line 24
def full_query(q, filters, from=0, sort=nil, only_title=false, size = Elasticsearch::Base::ITEMS_PER_PAGE)
  # , 'indices_boost' => {'irekia4' => 2.5, 'bopv' => 1}
  fq = { 'explain' => true, 'size' => size, 
         'from' => "#{from}", 'query' => query(q, filters, only_title), 'facets' => facets }
  fq.merge!(sort_string(sort))
  fq
end
query(q, filters, only_title) click to toggle source
# File app/models/elasticsearch/search.rb, line 32
def query(q, filters, only_title)
  if filters.present?
    { 'filtered' => { 'query' => query_string(q, only_title) }.merge(filters(filters)) }
  else
    # query_string(q.gsub(' AND ', ' ').gsub(/\s+/, ' AND '))
    query_string(q.gsub(/\s+/, ' '), only_title)
  end
end
query_string(q, only_title) click to toggle source
# File app/models/elasticsearch/search.rb, line 41
def query_string(q, only_title)
  if only_title                           
    fields = ['title_es^7', 'title_eu^7', 'title_en^7']                           
  else
    fields = ['title_es^7', 'title_eu^7', 'title_en^7', 'body_es', 'body_eu', 'body_en', 'tags^6', 'year', 'month', 
      'organization^5', 'areas^5', 'politicians^5', 'speaker^4', 'public_name^7', 'role^7', 'subtitles_es', 'subtitles_eu', 'subtitles_en']  
    fields_bopv = ['materias', 'seccion', 'rango', 'organo', 'no_bol', 'no_disp', 'no_orden']
    fields = fields + fields_bopv
  end    
  { 'query_string' => { 'fields' => fields, 'query' => "#{q}", 'default_operator' => 'AND', 'analyzer' => 'default'} }
end
sort_string(sort) click to toggle source
# File app/models/elasticsearch/search.rb, line 76
def sort_string(sort)
  if sort.present? && sort.eql?('date')
    {'sort' => {'published_at' => {'order' => 'desc'} }}        
  else                                                      
    {'sort' => ['_score', {'published_at' => {'order' => 'desc'} }]}
  end    
end