diff --git a/lib/search.rb b/lib/search.rb index 19251398138..7d3c167c08e 100644 --- a/lib/search.rb +++ b/lib/search.rb @@ -206,7 +206,8 @@ class Search end end - def posts_query(limit) + def posts_query(limit, opts=nil) + opts ||= {} posts = Post.includes(:post_search_data, {:topic => :category}) .where("topics.deleted_at" => nil) .where("topics.visible") @@ -234,8 +235,14 @@ class Search end posts = posts.order("TS_RANK_CD(TO_TSVECTOR(#{query_locale}, topics.title), #{ts_query}) DESC") - .order("TS_RANK_CD(post_search_data.search_data, #{ts_query}) DESC") - .order("topics.bumped_at DESC") + + data_ranking = "TS_RANK_CD(post_search_data.search_data, #{ts_query})" + if opts[:aggregate_search] + posts = posts.order("SUM(#{data_ranking}) DESC") + else + posts = posts.order("#{data_ranking} DESC") + end + posts = posts.order("topics.bumped_at DESC") if secure_category_ids.present? posts = posts.where("(categories.id IS NULL) OR (NOT categories.read_restricted) OR (categories.id IN (?))", secure_category_ids).references(:categories) @@ -270,6 +277,18 @@ class Search end end + def aggregate_search + cols = ['topics.id', 'topics.title', 'topics.slug'] + topics = posts_query(@limit, aggregate_search: true).group(*cols).pluck(*cols) + topics.each do |t| + @results.add_result(SearchResult.new(type: :topic, + topic_id: t[0], + id: t[0], + title: t[1], + url: "/t/#{t[2]}/#{t[0]}")) + end + end + def topic_search posts = if @search_context.is_a?(User) @@ -277,10 +296,12 @@ class Search posts_query(@limit * Search.burst_factor) elsif @search_context.is_a?(Topic) posts_query(@limit).where('posts.post_number = 1 OR posts.topic_id = ?', @search_context.id) - else - posts_query(@limit).where(post_number: 1) + elsif @include_blurbs + posts_query(@limit).where('posts.post_number = 1') end + # If no context, do an aggregate search + return aggregate_search if posts.nil? posts.each do |p| @results.add_result(SearchResult.from_post(p, @search_context, @term, @include_blurbs)) diff --git a/lib/search/search_result_type.rb b/lib/search/search_result_type.rb index 85c9038a20a..a9d4e35e3ab 100644 --- a/lib/search/search_result_type.rb +++ b/lib/search/search_result_type.rb @@ -28,4 +28,4 @@ class Search end end -end \ No newline at end of file +end diff --git a/spec/components/search_spec.rb b/spec/components/search_spec.rb index 5f8eac105cd..29b4ce20b56 100644 --- a/spec/components/search_spec.rb +++ b/spec/components/search_spec.rb @@ -195,7 +195,9 @@ describe Search do it 'returns the post' do result.should be_present result[:title].should == topic.title - result[:url].should == reply.url + + # The link is to the topic url because it's aggregated + result[:url].should == topic.relative_url end end