Class: Silver::Search
- Inherits:
-
Object
- Object
- Silver::Search
- Defined in:
- lib/silver/search.rb
Overview
Searches an indexed database. What else would it do?
Instance Method Summary collapse
-
#find_matching_phones(phones) ⇒ Object
Takes an array of metaphones and returns the matching keys in the index.
-
#initialize(query, key, redis_options = {}, number = 30, offset = 0) ⇒ Search
constructor
Takes a query and a redis key from a previous indexing.
-
#morph_words ⇒ Object
Takes the instance’s query, splits it into words, metaphones each word and returns the array of metaphoned words.
-
#perform(&accessor) ⇒ Object
Send a query to be metaphoned, finds the matching ids for the query and then returns the results.
Constructor Details
#initialize(query, key, redis_options = {}, number = 30, offset = 0) ⇒ Search
15 16 17 18 19 20 21 22 |
# File 'lib/silver/search.rb', line 15 def initialize(query,key,={},number=30,offset=0) @query = query @key = key @number = number @offset = offset @r = Redis.new() @r.select 12 end |
Instance Method Details
#find_matching_phones(phones) ⇒ Object
Takes an array of metaphones and returns the matching keys in the index. Since we are using double metaphone, it unions the results for the two possible metaphones.i
56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/silver/search.rb', line 56 def find_matching_phones(phones) phones.map! do |phone| if phone "#{@key}:#{phone}" else nil end end phones = @r.zunionstore "temp", phones.compact phones = @r.zrevrange "temp", 0, -1 phones end |
#morph_words ⇒ Object
Takes the instance’s query, splits it into words, metaphones each word and returns the array of metaphoned words.
47 48 49 50 51 |
# File 'lib/silver/search.rb', line 47 def morph_words words = @query.split(/[^a-zA-Z0-9]/) morphed_words = words.map{|word| [word,Text::Metaphone.(word)]} morphed_words end |
#perform(&accessor) ⇒ Object
Send a query to be metaphoned, finds the matching ids for the query and then returns the results. Finally it only returns entries that are shared by both words.
Takes a block that takes an id and then queries the database for that row. Again, Silver can be used for services that “row” is a bad metaphor like REST apis. However, it is easy to write.
Ex:
search.perform{|id| Picture.get(id) }
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/silver/search.rb', line 34 def perform(&accessor) morphed_words = morph_words morphed_words.map! do |word| phones = word[1] phones = self.find_matching_phones(phones) phones end results = morphed_words.reduce{|memo,obj| memo & obj}.slice(@offset,@number) results.map{|result| accessor.call(result)} end |