diff --git a/app/models/article.rb b/app/models/article.rb index 14450b574..b03c9ecde 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -76,18 +76,24 @@ class Article < ApplicationRecord scope :order_by_views, -> { reorder(views: :desc) } # TODO: if text search slows down https://www.postgresql.org/docs/current/textsearch-features.html#TEXTSEARCH-UPDATE-TRIGGERS + # - the A, B and C are for weightage. See: https://github.com/Casecommons/pg_search#weighting + # - the normalization is for ensuring the long articles that mention the search term too many times are not ranked higher. + # it divides rank by log(document_length) to prevent longer articles from ranking higher just due to sizeSee: https://github.com/Casecommons/pg_search#normalization + # - the ranking is to ensure that articles with higher weightage are ranked higher pg_search_scope( :text_search, - against: %i[ - title - description - content - ], + against: { + title: 'A', + description: 'B', + content: 'C' + }, using: { tsearch: { - prefix: true + prefix: true, + normalization: 2 } - } + }, + ranked_by: ':tsearch' ) def self.search(params) diff --git a/app/services/search_service.rb b/app/services/search_service.rb index 40d862b19..7fce0a7dd 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -96,7 +96,6 @@ class SearchService def filter_articles @articles = current_account.articles .text_search(search_query) - .reorder('updated_at DESC') .page(params[:page]) .per(15) end diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb index 22809d042..92c397ab7 100644 --- a/spec/services/search_service_spec.rb +++ b/spec/services/search_service_spec.rb @@ -156,33 +156,18 @@ describe SearchService do end context 'when article search' do - it 'orders results by updated_at desc' do - # Create articles with explicit timestamps - older_time = 2.days.ago - newer_time = 1.hour.ago - + it 'returns matching articles' do article2 = create(:article, title: 'Spellcasting Guide', account: account, portal: portal, author: user, status: 'published') - # rubocop:disable Rails/SkipsModelValidations - article2.update_column(:updated_at, older_time) - # rubocop:enable Rails/SkipsModelValidations - article3 = create(:article, title: 'Spellcasting Manual', account: account, portal: portal, author: user, status: 'published') - # rubocop:disable Rails/SkipsModelValidations - article3.update_column(:updated_at, newer_time) - # rubocop:enable Rails/SkipsModelValidations params = { q: 'Spellcasting' } search = described_class.new(current_user: user, current_account: account, params: params, search_type: 'Article') results = search.perform[:articles] - # Check the timestamps to understand ordering - results.map { |a| [a.id, a.updated_at] } - - # Should be ordered by updated_at desc (newer first) expect(results.length).to eq(2) - expect(results.first.updated_at).to be > results.second.updated_at + expect(results.map(&:id)).to contain_exactly(article2.id, article3.id) end it 'returns paginated results' do