From 3081ad72d5c3d64e3accbde27f6755710c8fa9c0 Mon Sep 17 00:00:00 2001 From: Akhtam Date: Tue, 10 Nov 2020 21:40:26 -0800 Subject: [PATCH 1/3] setup --- app/controllers/resources_controller.rb | 9 ++++ app/services/resources/search.rb | 71 +++++++++++++++++++++++++ config/routes.rb | 1 + 3 files changed, 81 insertions(+) create mode 100644 app/services/resources/search.rb diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 939002dd..38f670ef 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -13,6 +13,15 @@ def show render json: ResourcesPresenter.present(resource) end + def search + p "here" + result = Resources::Search.perform(params.require(:query), lat_lng: lat_lng, scope: resources) + # root: :resources is required if Algolia is used since Jsonite won't wrap + # the result with a :resources key. + p result + render json: ResourcesPresenter.present(result, root: :resources) + end + def create resources = clean_resources_params.map { |r| Resource.new(r) } fix_resources(resources) diff --git a/app/services/resources/search.rb b/app/services/resources/search.rb new file mode 100644 index 00000000..976a13ef --- /dev/null +++ b/app/services/resources/search.rb @@ -0,0 +1,71 @@ +module Resources + module Search + def self.perform(query, lat_lng: nil, scope: Resource) + strategy = if Rails.configuration.x.algolia.enabled + AlgoliaStrategy + else + DatabaseStrategy + end + p strategy + p "from service" + strategy.perform(query, lat_lng, scope) + end + + class SearchStrategy + def self.perform(_query, _lat_lng, _scope) + raise NotImplementedError + end + end + + class DatabaseStrategy < SearchStrategy + SEARCH_CONFIG = 'english' + + # SEARCH_COLUMNS maps table names to an array of the columns in + # that table to search. + SEARCH_COLUMNS = { + resources: %i[ + name + short_description + long_description + website + ].freeze, + services: :long_description, + notes: :note, + categories: :name + }.freeze + + CLAUSE = SEARCH_COLUMNS.map do |t, cols| + Array.wrap(cols).map do |c| + "to_tsvector('#{SEARCH_CONFIG}', coalesce(#{t}.#{c}, ''))" + end + end.flatten.join('||').freeze + + def self.perform(query, lat_lng, scope) + sort = lat_lng.blank? ? 'resources.name' : Address.distance_sql(lat_lng) + + scope + .left_outer_joins(services: [:categories]) + .left_outer_joins(:notes) + .left_outer_joins(:categories) + .left_outer_joins(:addresses) + .where("#{CLAUSE} @@ plainto_tsquery('#{SEARCH_CONFIG}', ?)", query) + .group('resources.id, addresses.latitude, addresses.longitude') + .order(sort) + end + end + + class AlgoliaStrategy < SearchStrategy + def self.perform(query, lat_lng, scope) + opts = if lat_lng.blank? + {} + else + { + aroundLatLng: "#{lat_lng.lat}, #{lat_lng.lng}", + aroundRadius: 20_000 # Meters + } + end + scope.algolia_search(query, opts) + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 6accd433..15565422 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,6 +18,7 @@ resources :resources do resources :notes, only: :create collection do + get :search get :count end From 9ffdf3b829830ed56f2eff0887ffbde3ae75b070 Mon Sep 17 00:00:00 2001 From: Akhtam Date: Tue, 10 Nov 2020 22:49:50 -0800 Subject: [PATCH 2/3] remove comments --- app/controllers/resources_controller.rb | 5 ++--- app/services/resources/search.rb | 9 ++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index 38f670ef..dc4c4d40 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -14,12 +14,11 @@ def show end def search - p "here" + p resources result = Resources::Search.perform(params.require(:query), lat_lng: lat_lng, scope: resources) # root: :resources is required if Algolia is used since Jsonite won't wrap # the result with a :resources key. - p result - render json: ResourcesPresenter.present(result, root: :resources) + # render json: ResourcesPresenter.present(result, root: :resources) end def create diff --git a/app/services/resources/search.rb b/app/services/resources/search.rb index 976a13ef..df3e6fd3 100644 --- a/app/services/resources/search.rb +++ b/app/services/resources/search.rb @@ -2,12 +2,11 @@ module Resources module Search def self.perform(query, lat_lng: nil, scope: Resource) strategy = if Rails.configuration.x.algolia.enabled - AlgoliaStrategy - else - DatabaseStrategy - end + AlgoliaStrategy + else + DatabaseStrategy + end p strategy - p "from service" strategy.perform(query, lat_lng, scope) end From b0fa8bafcc169653b746df12c8ba4e37f35a1734 Mon Sep 17 00:00:00 2001 From: Akhtam Date: Fri, 13 Nov 2020 22:53:34 -0800 Subject: [PATCH 3/3] remove prints --- app/controllers/resources_controller.rb | 4 ++-- app/services/resources/search.rb | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/resources_controller.rb b/app/controllers/resources_controller.rb index dc4c4d40..2ede95b6 100644 --- a/app/controllers/resources_controller.rb +++ b/app/controllers/resources_controller.rb @@ -14,11 +14,11 @@ def show end def search - p resources + p params[:query] result = Resources::Search.perform(params.require(:query), lat_lng: lat_lng, scope: resources) # root: :resources is required if Algolia is used since Jsonite won't wrap # the result with a :resources key. - # render json: ResourcesPresenter.present(result, root: :resources) + render json: ResourcesPresenter.present(result, root: :resources) end def create diff --git a/app/services/resources/search.rb b/app/services/resources/search.rb index df3e6fd3..8e7b5358 100644 --- a/app/services/resources/search.rb +++ b/app/services/resources/search.rb @@ -6,7 +6,6 @@ def self.perform(query, lat_lng: nil, scope: Resource) else DatabaseStrategy end - p strategy strategy.perform(query, lat_lng, scope) end