Skip to content

Commit 3997ce5

Browse files
authored
FIX: sort by topic activity when searching in:title (#36630)
When using `in:title` (or `t`), search results were sorted by the first post's creation date instead of the topic's last activity. This caused topics with recent replies to appear lower than older topics with no activity, which was unintuitive. For example, a topic created 5 years ago with a reply yesterday would appear below a topic created last week with no replies, even though the user expects "Latest Post" to show recently active topics first. Now when `@in_title` is true, we sort by `topics.bumped_at` instead of `posts.created_at`, matching user expectations for topic-level searches. Internal ref - t/170642
1 parent 536acef commit 3997ce5

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/search.rb

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,13 +844,17 @@ def apply_order(
844844
type_filter: "all_topics"
845845
)
846846
if @order == :latest
847-
if aggregate_search
847+
if @in_title
848+
posts = posts.order("topics.bumped_at DESC")
849+
elsif aggregate_search
848850
posts = posts.order("MAX(posts.created_at) DESC")
849851
else
850852
posts = posts.reorder("posts.created_at DESC")
851853
end
852854
elsif @order == :oldest
853-
if aggregate_search
855+
if @in_title
856+
posts = posts.order("topics.bumped_at ASC")
857+
elsif aggregate_search
854858
posts = posts.order("MAX(posts.created_at) ASC")
855859
else
856860
posts = posts.reorder("posts.created_at ASC")

spec/lib/search_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,6 +2841,33 @@ def indexed_post(*args)
28412841
results = Search.execute("in:title status:open Discourse")
28422842
expect(results.posts.length).to eq(1)
28432843
end
2844+
2845+
it "sorts by topic bumped_at" do
2846+
old_bumped_topic =
2847+
Fabricate(:topic, title: "Old bumped topic about Discourse", bumped_at: 1.day.ago)
2848+
new_bumped_topic =
2849+
Fabricate(:topic, title: "New bumped topic about Discourse", bumped_at: 1.hour.ago)
2850+
2851+
Fabricate(
2852+
:post,
2853+
topic: old_bumped_topic,
2854+
raw: "This is the first post",
2855+
created_at: 1.hour.ago,
2856+
)
2857+
2858+
Fabricate(
2859+
:post,
2860+
topic: new_bumped_topic,
2861+
raw: "This is the first post",
2862+
created_at: 1.day.ago,
2863+
)
2864+
2865+
results = Search.execute("Discourse in:title order:latest")
2866+
expect(results.posts.map(&:topic_id)).to eq([new_bumped_topic.id, old_bumped_topic.id])
2867+
2868+
results = Search.execute("Discourse in:title order:oldest")
2869+
expect(results.posts.map(&:topic_id)).to eq([old_bumped_topic.id, new_bumped_topic.id])
2870+
end
28442871
end
28452872

28462873
describe "include:invisible / include:unlisted" do

0 commit comments

Comments
 (0)