module Lunar class Search attr :sets, :prefix, :search_identifier, :fuzzy_sets def initialize(prefix, keywords) if keywords.is_a?(Hash) if fuzzy_hash = keywords.delete(:fuzzy) @fuzzy_sets = fuzzy_hash.inject([]) { |a, (field, query)| a | FuzzySets.new(prefix, query, field) } @search_identifier = fuzzy_hash.hash else @sets = keywords.inject([]) { |a, (field, query)| a | Sets.new(prefix, query, field) } @search_identifier = keywords.hash end else @sets = Sets.new(prefix, keywords) @search_identifier = keywords.hash end @prefix = prefix # Default finder, uses Ohm style finding @finder = lambda { |id| prefix[id] } end def results(&block) block ||= @finder if sets if sets.empty? return [] else if not Lunar.redis.exists(dist_key) Lunar.redis.zunion dist_key, sets.size, *sets Lunar.redis.expire dist_key, Lunar.ttl end SortedResultSet.new(dist_key, &block) end elsif fuzzy_sets if fuzzy_sets.empty? return [] else if not Lunar.redis.exists(dist_key) Lunar.redis.sunionstore dist_key, *fuzzy_sets Lunar.redis.expire dist_key, Lunar.ttl end UnsortedResultSet.new(dist_key, &block) end end end protected def dist_key Lunar.nest[:Results][search_identifier] end end end