Created
September 25, 2012 03:26
-
-
Save waynerobinson/3779810 to your computer and use it in GitHub Desktop.
Cached Autocompleter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Autocompleter | |
def self.parse_street_input(input) | |
matches = / | |
( | |
(?:[Uu](?:nit)?\s*)? #U or Unit, any casing, maybe with following spaces, non-captured | |
[\d\/\s\\\-,]+ #Unit number (Digits, spaces, dashes, both slashes) | |
\d?) #Street Number | |
?\s? #Spacing and Optionality for Numbering | |
([\w\-\s']+) #Street Name - Match any combination of words and spaces (And apostrophe) | |
/x.match(input) | |
numbermatch = / | |
(?: | |
(?:[Uu]nit\s*)? #Unit word | |
(\d+?) #Unit number | |
\s*[\/\-\\,\s]\s* #Unit separator - Any number of spaces surrounding | |
)? | |
(\d+) #Street number | |
/x.match(matches[1]) || [] | |
{:number => numbermatch[2], :unit => numbermatch[1], :street => matches[2]} | |
end | |
def self.get_auto_complete_suggestions(fleet, street) | |
MTDataStone.addresses.get_autocomplete_suggestions(fleet, street) | |
end | |
def self.autocomplete(autocompletion_term) | |
autocomplete_terms = prepare_autocomplete_term(autocompletion_term) | |
result_set = [] | |
if proceed_with_search?(autocomplete_terms) | |
autocompletion_data = get_autocomplete_suggestions(7, autocomplete_terms[:street]) | |
puts "ACD: #{autocompletion_data}" | |
result_set = build_autocompletion_result_set(autocomplete_terms, autocompletion_data) | |
end | |
end | |
def self.prepare_autocomplete_term(autocompletion_term) | |
term_hash = Autocompleter.parse_street_input(autocompletion_term) | |
term_hash = self.filter_symbols(term_hash) | |
end | |
def self.build_autocompletion_result_set(autocomplete_term, autocompletion_data) | |
autocomplete_set = [] | |
# Putting records into the DB to save passing all the data to the front end. | |
autocompletion_data.each do |ac| | |
query_terms = {:street_name => ac.street_name, :suburb_name => ac.suburb_name, :designation_name => ac.designation_name, | |
:unit_number => autocomplete_term[:unit], :street_number => autocomplete_term[:number], | |
:street_id => ac.street_id, :designation_id => ac.designation_id, :suburb_id => ac.suburb_id} | |
stripped_query_terms = query_terms.delete_if {|k,v| v.nil?} | |
autocomplete_item = MtDataAddress.find_or_create_full_record(stripped_query_terms) | |
autocomplete_item.save if autocomplete_item.new_record? | |
autocomplete_set << autocomplete_item | |
end | |
return autocomplete_set | |
end | |
# Returns true if it is worthwhile checking for street completion, otherwise returns false | |
def self.proceed_with_search?(terms) | |
terms[:street].length > 2 | |
end | |
def self.filter_symbols(unfiltered_terms) | |
filtered_results = unfiltered_terms.clone | |
filtered_results[:street] = unfiltered_terms[:street].delete("'").capitalize | |
filtered_results | |
end | |
end | |
class CachedAutocompleter < Autocompleter | |
EXPIRY_PERIOD = 60.days | |
def self.get_auto_complete_suggestions(fleet, street) | |
cached_or_cache("#{fleet}:#{street}") do | |
super(fleet, street) | |
end | |
end | |
def self.cached_or_cache(key, &block) | |
cached = fetch_cached(key) | |
unless cached | |
cached = yield | |
set_cached(key, cached) | |
end | |
cached | |
end | |
def self.fetch_cached(key) | |
cached_result = AutocompleterCache.where(:query => key).first | |
if cached_result && (cached_result.updated_at + EXPIRY_PERIOD) > Time.current | |
YAML.load(cached_result.data) | |
elsif cached_result | |
cached_result.delete | |
end | |
end | |
def self.set_cached(key, value) | |
cached_result = AutocompleterCache.where(:query => key).first | |
cached_result ||= AutocompleterCache.new(:query => key) | |
cached_result.data = value.to_yaml | |
cached_result.save! # will only execute if data is different | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment