diff --git a/app/models/concerns/search_cache.rb b/app/models/concerns/search_cache.rb new file mode 100644 index 000000000..1d4d5a039 --- /dev/null +++ b/app/models/concerns/search_cache.rb @@ -0,0 +1,27 @@ +module SearchCache + extend ActiveSupport::Concern + + included do + after_save :calculate_tsvector + end + + def calculate_tsvector + ActiveRecord::Base.connection.execute(" + UPDATE proposals SET tsv = (#{searchable_values_sql}) WHERE id = #{self.id}") + end + + private + + def searchable_values_sql + searchable_values.collect { |value, weight| set_tsvector(value, weight) }.join(" || ") + end + + def set_tsvector(value, weight) + "setweight(to_tsvector('spanish', coalesce(#{quote(value)}, '')), #{quote(weight)})" + end + + def quote(value) + ActiveRecord::Base.connection.quote(value) + end + +end \ No newline at end of file diff --git a/app/models/proposal.rb b/app/models/proposal.rb index dd2560ba1..1f3518144 100644 --- a/app/models/proposal.rb +++ b/app/models/proposal.rb @@ -5,6 +5,7 @@ class Proposal < ActiveRecord::Base include Measurable include Sanitizable include PgSearch + include SearchCache apply_simple_captcha acts_as_votable @@ -50,13 +51,24 @@ class Proposal < ActiveRecord::Base tags: :name }, using: { - tsearch: { dictionary: "spanish" }, + tsearch: { dictionary: "spanish", tsvector_column: 'tsv' }, trigram: { threshold: 0.1 }, }, ranked_by: '(:tsearch + proposals.cached_votes_up)', order_within_rank: "proposals.created_at DESC" } + def searchable_values + values = { + title => 'A', + question => 'B', + summary => 'C', + description => 'D' + } + tag_list.each{ |tag| values[tag] = 'D' } + values + end + def description super.try :html_safe end diff --git a/db/migrate/20151111202657_adds_tsvector_update_trigger.rb b/db/migrate/20151111202657_adds_tsvector_update_trigger.rb new file mode 100644 index 000000000..ed60a259d --- /dev/null +++ b/db/migrate/20151111202657_adds_tsvector_update_trigger.rb @@ -0,0 +1,13 @@ +class AddsTsvectorUpdateTrigger < ActiveRecord::Migration + + def up + add_column :proposals, :tsv, :tsvector + add_index :proposals, :tsv, using: "gin" + end + + def down + remove_index :proposals, :tsv + remove_column :proposals, :tsv + end + +end diff --git a/db/schema.rb b/db/schema.rb index 95bd4a36d..448fa1a8e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20151103194329) do +ActiveRecord::Schema.define(version: 20151111202657) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -95,10 +95,10 @@ ActiveRecord::Schema.define(version: 20151103194329) do t.string "visit_id" t.datetime "hidden_at" t.integer "flags_count", default: 0 + t.datetime "ignored_flag_at" t.integer "cached_votes_total", default: 0 t.integer "cached_votes_up", default: 0 t.integer "cached_votes_down", default: 0 - t.datetime "ignored_flag_at" t.integer "comments_count", default: 0 t.datetime "confirmed_hide_at" t.integer "cached_anonymous_votes_total", default: 0 @@ -114,7 +114,6 @@ ActiveRecord::Schema.define(version: 20151103194329) do add_index "debates", ["cached_votes_total"], name: "index_debates_on_cached_votes_total", using: :btree add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree add_index "debates", ["confidence_score"], name: "index_debates_on_confidence_score", using: :btree - add_index "debates", ["description"], name: "index_debates_on_description", using: :btree add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree add_index "debates", ["hot_score"], name: "index_debates_on_hot_score", using: :btree add_index "debates", ["title"], name: "index_debates_on_title", using: :btree @@ -215,18 +214,19 @@ ActiveRecord::Schema.define(version: 20151103194329) do t.text "summary" t.string "video_url" t.integer "physical_votes", default: 0 + t.tsvector "tsv" end add_index "proposals", ["author_id", "hidden_at"], name: "index_proposals_on_author_id_and_hidden_at", using: :btree add_index "proposals", ["author_id"], name: "index_proposals_on_author_id", using: :btree add_index "proposals", ["cached_votes_up"], name: "index_proposals_on_cached_votes_up", using: :btree add_index "proposals", ["confidence_score"], name: "index_proposals_on_confidence_score", using: :btree - add_index "proposals", ["description"], name: "index_proposals_on_description", using: :btree add_index "proposals", ["hidden_at"], name: "index_proposals_on_hidden_at", using: :btree add_index "proposals", ["hot_score"], name: "index_proposals_on_hot_score", using: :btree add_index "proposals", ["question"], name: "index_proposals_on_question", using: :btree add_index "proposals", ["summary"], name: "index_proposals_on_summary", using: :btree add_index "proposals", ["title"], name: "index_proposals_on_title", using: :btree + add_index "proposals", ["tsv"], name: "index_proposals_on_tsv", using: :gin create_table "settings", force: :cascade do |t| t.string "key" diff --git a/lib/tasks/debates.rake b/lib/tasks/debates.rake index ce37e2743..57902dc8f 100644 --- a/lib/tasks/debates.rake +++ b/lib/tasks/debates.rake @@ -1,6 +1,6 @@ namespace :debates do desc "Updates all debates by recalculating their hot_score" - task hot_score: :environment do + task touch: :environment do Debate.find_in_batches do |debates| debates.each(&:save) end diff --git a/lib/tasks/proposals.rake b/lib/tasks/proposals.rake index c2bf8742e..ddba8f913 100644 --- a/lib/tasks/proposals.rake +++ b/lib/tasks/proposals.rake @@ -1,6 +1,6 @@ namespace :proposals do desc "Updates all proposals by recalculating their hot_score" - task hot_score: :environment do + task touch: :environment do Proposal.find_in_batches do |proposals| proposals.each(&:save) end