Permalink
Browse files

using Tire gem for DRYing up the search codes

  • Loading branch information...
1 parent 28ce239 commit a5ced93d42157f25f603b16a661640009822d57b @bry4n bry4n committed Jul 10, 2012
Showing with 80 additions and 111 deletions.
  1. +1 −0 Gemfile
  2. +8 −0 Gemfile.lock
  3. +2 −2 app/controllers/site_controller.rb
  4. +4 −47 app/models/doc.rb
  5. +5 −56 app/models/section.rb
  6. +2 −6 config/initializers/elasticsearch.rb
  7. +58 −0 lib/searchable.rb
View
@@ -25,6 +25,7 @@ gem 'nestful'
gem "awesome_print"
gem 'newrelic_rpm'
gem 'exceptional'
+gem 'tire'
# Gems used only for assets and not required
# in production environments by default.
View
@@ -71,6 +71,7 @@ GEM
fssm (0.2.9)
haml (3.1.4)
hashie (1.2.0)
+ hashr (0.0.21)
heroku (2.24.1)
launchy (>= 0.3.2)
netrc (~> 0.7.1)
@@ -178,6 +179,12 @@ GEM
rack (>= 1.0.0)
thor (0.14.6)
tilt (1.3.3)
+ tire (0.4.2)
+ activemodel (>= 3.0)
+ hashr (~> 0.0.19)
+ multi_json (~> 1.0)
+ rake
+ rest-client (~> 1.6)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
@@ -223,5 +230,6 @@ DEPENDENCIES
taps
thin
tilt
+ tire
uglifier (>= 1.0.3)
yajl-ruby
@@ -39,11 +39,11 @@ def search_term(sname, highlight = false)
:results => []
}
- if results = Doc.search(sname, highlight)
+ if results = Doc.search(sname)
data[:results] << results
end
- if results = Section.search(sname, 'en', highlight)
+ if results = Section.search(sname, :lang => 'en')
data[:results] << results
end
View
@@ -1,59 +1,16 @@
require 'diff/lcs'
require 'pp'
+require 'searchable'
# t.text :blob_sha
# t.text :plain
# t.text :html
# t.timestamps
class Doc < ActiveRecord::Base
- has_many :doc_versions
-
- def self.search(term, highlight = false)
- query_options = {
- "bool" => {
- "should" => [],
- "minimum_number_should_match" => 1
- }
- }
-
- terms = term.split(/\s|-/)
- terms.each do |terma|
- query_options['bool']['should'] << { "prefix" => { "name" => { "value" => terma, "boost" => 12.0 } } }
- query_options['bool']['should'] << { "term" => { "text" => terma } }
- end
-
- highlight_options = {
- 'pre_tags' => ['[highlight]'],
- 'post_tags' => ['[xhighlight]'],
- 'fields' => { 'text' => {"fragment_size" => 200} }
- }
-
- options = { 'query' => query_options,
- 'size' => 10 }
- options['highlight'] = highlight_options
-
- resp = BONSAI.search('doc', options)
+
+ include Searchable
- ref_hits = []
- if resp
- resp['hits']['hits'].each do |hit|
- highlight = hit.has_key?('highlight') ? hit['highlight']['text'].first : nil
- name = hit["_source"]["name"]
- ref_hits << {
- :name => name,
- :score => hit["_score"],
- :highlight => highlight,
- :url => "/docs/#{name}"
- }
- end
- end
-
- if ref_hits.size > 0
- return { :category => "Reference", :term => term, :matches => ref_hits }
- else
- nil
- end
- end
+ has_many :doc_versions
# returns an array of the differences with 3 entries
# 0: additions
View
@@ -1,3 +1,5 @@
+require 'searchable'
+
# t.string :title
# t.integer :number
# t.string :slug
@@ -7,6 +9,9 @@
# t.belongs_to :chapter
# t.timestamps
class Section < ActiveRecord::Base
+
+ include Searchable
+
default_scope :order => 'number'
belongs_to :chapter
@@ -83,60 +88,4 @@ def index
nil # this is busted in production for some reason, which is really an issue
end
- def self.search(term, lang = 'en', highlight = false)
- query_options = {
- "bool" => {
- "must" => [
- { "term" => { "lang" => lang } }
- ],
- "should" => [],
- "minimum_number_should_match" => 1
- }
- }
-
- terms = term.split(/\s|-/)
- terms.each do |terma|
- query_options['bool']['should'] << { "prefix" => { "section" => { "value" => terma, "boost" => 12.0 } } }
- query_options['bool']['should'] << { "term" => { "html" => terma } }
- end
-
- highlight_options = {
- 'pre_tags' => ['[highlight]'],
- 'post_tags' => ['[xhighlight]'],
- 'fields' => { 'html' => {"fragment_size" => 200} }
- }
-
- options = { 'query' => query_options,
- 'size' => 10 }
- options['highlight'] = highlight_options
-
- resp = BONSAI.search('book', options)
-
- ref_hits = []
- if resp
- resp['hits']['hits'].each do |hit|
- name = hit["_source"]["section"]
- name = hit["_source"]["chapter"] if name.empty?
- slug = hit["_id"].gsub('---', '/')
- lang = hit["_source"]["lang"]
- meta = "Chapter " + hit["_source"]['number'] + ' : ' + hit["_source"]["chapter"]
- highlight = hit.has_key?('highlight') ? hit['highlight']['html'].first : nil
- ref_hits << {
- :name => name,
- :meta => meta,
- :score => hit["_score"],
- :highlight => highlight,
- :url => "/book/#{slug}"
- }
- end
- end
-
- if ref_hits.size > 0
- return { :category => "Book", :term => term, :matches => ref_hits }
- else
- nil
- end
-
- end
-
end
@@ -1,9 +1,5 @@
require 'elasticsearch'
-if ENV['SEARCH_INDEX_URL']
- ELASTICSEARCH = {
- url: ENV['SEARCH_INDEX_URL'],
- index_name: 'gitscm'
- }
- BONSAI = ElasticSearch::Index.new ELASTICSEARCH[:index_name], ELASTICSEARCH[:url]
+Tire.configure do
+ url (ENV["SEARCH_INDEX_URL"] || "http://0.0.0.0:9200")
end
View
@@ -0,0 +1,58 @@
+module Searchable
+ extend ActiveSupport::Concern
+
+ included do
+
+ def self.search(keywords, options = {})
+
+ class_name = self.name.to_s.downcase
+ search_type = (class_name == "section" ? "book" : "doc")
+ type_name = (search_type == "book" ? "section" : "name")
+ category_name = (search_type == "book" ? "Book" : "Reference")
+
+ query_options = {
+ "size" => 10,
+ "query" => {
+ "bool" => {
+ "should"=> [],
+ "minimum_number_should_match" => 1
+ },
+ },
+ "highlight" => {
+ "pre_tags" => ["[highlight]"],
+ "post_tags" => ["[xhighlight]"],
+ "fields" => { "html" => { "fragment_size" => 200 } }
+ }
+ }
+ lang_options = {"must" => [{ "term" => { "lang" => options[:lang] } }]}
+ query_options["query"]["bool"].merge!(lang_options) if options[:lang].present?
+
+ keywords.split(/\s|\-/).each do |keyword|
+ query_options['query']['bool']['should'] << { "prefix" => { type_name => { "value" => keyword, "boost" => 12.0 } } }
+ query_options['query']['bool']['should'] << { "term" => { "html" => keyword } }
+ end
+
+ search = Tire::Search::Search.new('gitscm', :type => search_type, :payload => query_options) rescue nil
+ if search
+ ref_hits = []
+ search.results.each do |result|
+ name = result.section || result.chapter || result.name
+ slug = result.id.gsub('---','/')
+ ref_hits << {
+ :name => name,
+ :meta => result.meta,
+ :score => result._score,
+ :highlight => result.highlight,
+ :url => (search_type == "book" ? "/book/#{slug}" : "/docs/#{name}")
+ }
+ end
+ if ref_hits.size > 0
+ return {:category => category_name, :term => keywords, :matches => ref_hits}
+ end
+ end
+
+ end
+
+ end
+
+end

0 comments on commit a5ced93

Please sign in to comment.