Class: SearchResult

Inherits:
Object
  • Object
show all
Defined in:
app/models/search_result.rb

Defined Under Namespace

Classes: KeyMatch, QueryResult, Synonym

Class Method Summary collapse

Class Method Details

.calculate_results_pages(results_count) ⇒ Object



65
66
67
68
69
# File 'app/models/search_result.rb', line 65

def self.calculate_results_pages(results_count)
  num_pages = results_count / 10
  num_pages = num_pages + 1 if results_count % 10 > 0
  num_pages
end

.create_query(query, options = {}) ⇒ Object



29
30
31
32
33
34
35
# File 'app/models/search_result.rb', line 29

def self.create_query(query, options={})
  opts = options.clone
  normalize_query_options(opts)
  opts[:query] = query
  opts[:engine] = GSA::Engine.new({:host => opts[:host]})
  GSA::Query.new(opts)
end

.create_url_for_query(options, query) ⇒ Object



107
108
109
110
# File 'app/models/search_result.rb', line 107

def self.create_url_for_query(options, query)
  normalize_query_options(options)
  return query_url(query, options)
end

.fetch_document(url) ⇒ Object

Given a URL, GET it and return the contents

Parameters:

  • url (String)

    A URL formatted string



131
132
133
134
# File 'app/models/search_result.rb', line 131

def self.fetch_document(url)
  Rails.logger.debug {"GSA: Fetching '#{url}'"}
  Net::HTTP.get(URI.parse(url))
end

.fetch_xml_doc(query, options = {}) ⇒ Object

Fetches the xml response from the google mini server.



137
138
139
140
141
# File 'app/models/search_result.rb', line 137

def self.fetch_xml_doc(query, options={})
  url = create_url_for_query(options, query)
  response = fetch_document(url)
  REXML::Document.new(response)
end

.find(query, options = {}) ⇒ Object

Queries google mini by a specific URL to find all the results. Converts XML results to a paging results of Search Results.

See SearchResult#query_url for acceptable options params



19
20
21
22
23
24
25
26
27
# File 'app/models/search_result.rb', line 19

def self.find(query, options={})
  return QueryResult.new unless query
  xml_doc = fetch_xml_doc(query, options)
  results = parse_xml(xml_doc, options)
  results.query = query
  portlet = find_search_engine_portlet(options)
  results.path = portlet.path 
  results
end

.find_search_engine_portlet(options) ⇒ Object



121
122
123
124
125
126
127
# File 'app/models/search_result.rb', line 121

def self.find_search_engine_portlet(options)
  portlet = GoogleMiniSearchEnginePortlet.new
  if options[:portlet]
    portlet = options.delete(:portlet)
  end
  portlet
end

.new_gsa(portlet) ⇒ Object

Creates a new GSA::Appliance from a GoogleMiniSearchPortlet.



8
9
10
11
12
# File 'app/models/search_result.rb', line 8

def self.new_gsa(portlet)
  options = {:portlet=>portlet}
  normalize_query_options(options)
  GSA::Appliance.new(options)
end

.normalize_query_options(options) ⇒ Object



112
113
114
115
116
117
118
119
# File 'app/models/search_result.rb', line 112

def self.normalize_query_options(options)
  portlet = find_search_engine_portlet(options)
  options[:front_end] = portlet.front_end_name
  options[:collection] = portlet.collection_name
  options[:host] = portlet.service_url

  options[:collection] = options.delete(:site) if options[:site]
end

.parse_hits(xml_doc) ⇒ Object



43
44
45
46
47
48
49
50
# File 'app/models/search_result.rb', line 43

def self.parse_hits(xml_doc)
  root = xml_doc.root
  results = []
  xml_doc.elements.each('GSP/RES/R') do |ele|
    results << GSA::Result.new(ele)
  end
  results
end

.parse_key_matches(xml_doc) ⇒ Object



143
144
145
146
147
148
149
150
151
152
# File 'app/models/search_result.rb', line 143

def self.parse_key_matches(xml_doc)
  matches = []
  xml_doc.elements.each('GSP/GM') do |ele|
    key_match = KeyMatch.new
    key_match.url = ele.elements["GL"].text
    key_match.title = ele.elements["GD"].text
    matches << key_match
  end
  matches
end

.parse_results_count(xml_doc) ⇒ Object



37
38
39
40
41
# File 'app/models/search_result.rb', line 37

def self.parse_results_count(xml_doc)
  root = xml_doc.root
  count = root.elements["RES/M"]
  count ? count.text.to_i : 0
end

.parse_synonyms(xml_doc, query_result) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
# File 'app/models/search_result.rb', line 154

def self.parse_synonyms(xml_doc, query_result)
  synonyms = []
  xml_doc.elements.each('GSP/Synonyms/OneSynonym') do |ele|
    synonym = Synonym.new
    synonym.query = ele.attributes["q"]
    synonym.label = ele.text
    synonym.query_result = query_result
    synonyms << synonym
  end
  synonyms
end

.parse_xml(xml_doc, options = {}) ⇒ Object



52
53
54
55
56
57
58
59
60
61
# File 'app/models/search_result.rb', line 52

def self.parse_xml(xml_doc, options={})
  hits = parse_hits(xml_doc)
  results = QueryResult.new(hits)
  results.key_matches= parse_key_matches(xml_doc)
  results.synonyms = parse_synonyms(xml_doc, results)
  results.results_count = parse_results_count(xml_doc)
  results.num_pages = calculate_results_pages(results.results_count)
  results.start = options[:start] ? options[:start] : 0
  results
end

.query_url(query, options) ⇒ Object

Construct a query url for the GSA.

Parameters:

  • query (String)
  • options (Hash)
  • :host (Hash)

    a customizable set of options

  • :start (Hash)

    a customizable set of options

  • :front_end (Hash)

    a customizable set of options

  • :collection (Hash)

    a customizable set of options

  • :sort (Hash)

    a customizable set of options

  • :as_xml (Hash)

    a customizable set of options



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
# File 'app/models/search_result.rb', line 81

def self.query_url(query, options)
  options[:as_xml] = true if options[:as_xml].nil?

  encoded_query = CGI::escape(query)

  # Turns off automatic results filter (filter=0), which when set to 1, allows mini to reduces the # of similar/duplicate results,
  # but makes it hard to determine the total # of results.
  url = "#{options[:host]}/search?q=#{encoded_query}&output=xml_no_dtd&client=#{options[:front_end]}&site=#{options[:collection]}&filter=0"
  if options[:start]
    url = url + "&start=#{options[:start]}"
  end

  if options[:sort]
    url += "&sort=#{CGI::escape(options[:sort])}"
  end

  unless options[:as_xml]
    url += "&proxystylesheet=#{options[:front_end]}"
  end

  # Ensure both results (oe) and query/input values (ie) are interpreted as UTF-8.
  # See http://code.google.com/apis/searchappliance/documentation/46/xml_reference.html#request_i18n
  url += "&oe=UTF-8&ie=UTF-8"
  return url
end