Last active
August 29, 2015 14:05
-
-
Save bayleedev/be9cd721199825fa835b to your computer and use it in GitHub Desktop.
This file contains 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
require 'pry' # who doesn't want pry? | |
# Adds a `find` method to every model | |
module Finder | |
attr_accessor :types | |
def queries(*args) | |
@types = args | |
end | |
def find(request) | |
request = SolrRequest.new(request) | |
@types.each do |type| | |
klass = snake_to_const(type) | |
return klass.new.handle(request) if klass.handle?(request) | |
end | |
false | |
end | |
def snake_to_const(title) | |
Object.const_get(title.to_s.split('_').map { |e| e.capitalize }.join) | |
end | |
end | |
# Provider Model, has two solr query classes ProviderBySpecialty, ProviderByName | |
class Provider | |
extend Finder | |
queries :provider_by_specialty, :provider_by_name | |
end | |
# Location Model has one solr query class LocationByName | |
class Location | |
extend Finder | |
queries :location_by_name | |
end | |
# Creates the ProviderBySpecialty query | |
class ProviderBySpecialty | |
def self.handle?(request) | |
request.handle?({ | |
need: [:specialist_id, :location], | |
want: [:distance, :standing_code, :facets, :fields, :limit] | |
}) | |
end | |
def fields | |
(%w(score provider_id master_id geo specialist_id standing_code) + | |
%w(provider_practice_id disorder_id name_combo first_name middle_name) + | |
%w(last_name alias_first_name alias_middle_name alias_last_name) + | |
%w(alias_suffix display_name serial_SearchProviders)).join(',') | |
end | |
def facets(fields) | |
fields ||= [:us_educated, :is_abms_certified, :is_top_doctor, :is_patients_choice, :degree, :gender, :language_id] | |
fields.map do |field| | |
"facet.field={!key=#{field}}#{field}" | |
end | |
end | |
def handle(request) | |
[ | |
'/providers_primary/select?wt=json', | |
"q=specialist_id:#{request.specialist_id} AND standing_code:#{request.standing_code || 'P'}", | |
"fl=#{request.fields || fields}", | |
"sort=sum(product(recip(geodist(geo,#{request.location}),0.2,1,1), 70), product(physician_algorithm_quality, 30)) desc", | |
'facet=true', | |
facets(request.facets), | |
'facet.range={!key=experience}experience', | |
'f.experience.facet.range.start=5', | |
'f.experience.facet.range.end=1000', | |
'f.experience.facet.range.gap=5', | |
'facet.range={!key=avg_wait_time}avg_wait_time', | |
'f.avg_wait_time.facet.range.start=0', | |
'f.avg_wait_time.facet.range.end=1000', | |
'f.avg_wait_time.facet.range.gap=10', | |
'facet.mincount=1', | |
"fq={!bbox pt=#{request.location} sfield=geo d=#{request.distance || '24.14016'}", | |
"rows=#{request.limit || 25}", | |
'defType=edismax' | |
].join('&') | |
end | |
end | |
# Creates the LocationByName query | |
class LocationByName | |
def self.handle?(request) | |
request.handle?(need: [:name], want: [:order, :fields]) | |
end | |
def fields | |
%w(state city state_full geo:cc_geo zip aliases type population state_full geo geo_cc).join(',') | |
end | |
def handle(request) | |
[ | |
'/places_primary/select?wt=json', | |
"q=((type:zip AND aliases_s_mv:(*\ #{request.name}* #{request.name}*)) OR city_s:(*\ #{request.name}* #{request.name}*))", | |
"fl=#{request.fields || fields}", | |
'fq={!tag=type}type:(city zip)', | |
"sort=#{request.order || 'population'} desc", | |
'group=true', | |
'group.field=city_state_s', | |
'group.sort=type asc,population desc', | |
'group.limit=1', | |
'group.ngroups=true', | |
'group.cache.percent=0', | |
'group.truncate=true', | |
'group.facet=false', | |
'rows=20', | |
'defType=edismax' | |
].join('&') | |
end | |
end | |
# Creates the ProviderByName query | |
class ProviderByName | |
def self.handle?(request) | |
request.handle?(need: [:name], want: [:fields, :facets]) | |
end | |
def facets(fields) | |
fields ||= [:us_educated, :is_abms_certified, :is_top_doctor, :is_patients_choice, :degree, :gender, :language_id] | |
fields.map do |field| | |
"facet.field={!key=#{field}}#{field}" | |
end | |
end | |
def fields | |
(%w(score provider_id master_id geo specialist_id standing_code) + | |
%w(provider_practice_id disorder_id name_combo first_name middle_name) + | |
%w(last_name alias_first_name alias_middle_name alias_last_name) + | |
%w(alias_suffix display_name serial_SearchProviders)).join(',') | |
end | |
def handle(request) | |
[ | |
'/providers_primary/select?wt=json', | |
"q=(display_name:#{request.name}*)", | |
"fl=#{request.fields || fields}", | |
'sort=geodist(geo,40.7142,-74.0064) asc, score desc', | |
'facet=true', | |
facets(request.facets), | |
'facet.range={!key=experience}experience', | |
'f.experience.facet.range.start=5', | |
'f.experience.facet.range.end=1000', | |
'f.experience.facet.range.gap=5', | |
'facet.range={!key=avg_wait_time}avg_wait_time', | |
'f.avg_wait_time.facet.range.start=0', | |
'f.avg_wait_time.facet.range.end=1000', | |
'f.avg_wait_time.facet.range.gap=10', | |
'facet.mincount=1', | |
'fq={!bbox pt=40.7142,-74.0064 sfield=geo d=10000}', | |
'rows=25', | |
'defType=edismax' | |
].join('&') | |
end | |
end | |
# Awesome param object that can help determine if you want him or not. | |
class SolrRequest | |
attr_accessor :params | |
def initialize(params = {}) | |
@params = params | |
end | |
def handle_all_needs?(needs) | |
(needs & params.keys) == needs | |
end | |
def handle_only_wants?(wants) | |
(params.keys & wants) == params.keys | |
end | |
def handle?(qualifications) | |
handle_all_needs?(qualifications[:need]) and | |
handle_only_wants?(qualifications[:need] + qualifications[:want]) | |
end | |
def method_missing(method, *args) | |
params[method] | |
end | |
end | |
# Example | |
puts Location.find(name: 'blaine') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment