FEATURE: search_rank_sort_priorities modifier (#21329)

This new modifier can be used by plugins to modify search ordering.

Specifically plugins such as discourse_solved can amend search ordering
so solved topics bump to the top.

Also correct edge case where low and high sort priority categories did not
order correctly when it came to closed/archived
This commit is contained in:
Sam 2023-05-02 16:36:36 +10:00 committed by GitHub
parent a8e28060d1
commit c63551d227
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 16 deletions

View File

@ -1153,20 +1153,28 @@ class Search
)
SQL
rank_sort_priorities = [["topics.archived", 0.85], ["topics.closed", 0.9]]
rank_sort_priorities =
DiscoursePluginRegistry.apply_modifier(
:search_rank_sort_priorities,
rank_sort_priorities,
self,
)
category_priority_weights = <<~SQL
(
CASE categories.search_priority
WHEN #{Searchable::PRIORITIES[:low]}
THEN #{SiteSetting.category_search_priority_low_weight}
THEN #{SiteSetting.category_search_priority_low_weight.to_f}
WHEN #{Searchable::PRIORITIES[:high]}
THEN #{SiteSetting.category_search_priority_high_weight}
ELSE
CASE WHEN topics.archived
THEN 0.85
WHEN topics.closed
THEN 0.9
ELSE 1
THEN #{SiteSetting.category_search_priority_high_weight.to_f}
ELSE 1.0
END
*
CASE
#{rank_sort_priorities.sort_by { |_, pri| -pri }.map { |k, v| "WHEN #{k} THEN #{v}" }.join("\n")}
ELSE 1.0
END
)
SQL
@ -1302,8 +1310,6 @@ class Search
end
def aggregate_post_sql(opts)
default_opts = { type_filter: opts[:type_filter] }
min_id =
if SiteSetting.search_recent_regular_posts_offset_post_id > 0
if %w[all_topics private_message].include?(opts[:type_filter])

View File

@ -2654,6 +2654,34 @@ RSpec.describe Search do
end
end
context "when plugin introduces a search_rank_sort_priorities modifier" do
before do
SearchIndexer.enable
DiscoursePluginRegistry.clear_modifiers!
end
after do
SearchIndexer.disable
DiscoursePluginRegistry.clear_modifiers!
end
it "allow modifying the search rank" do
plugin = Plugin::Instance.new
plugin.register_modifier(:search_rank_sort_priorities) do |ranks, search|
[["topics.closed", 77]]
end
closed_topic = Fabricate(:topic, title: "saml saml saml is the best", closed: true)
closed_post = Fabricate(:post, topic: closed_topic, raw: "this topic is a story about saml")
open_topic = Fabricate(:topic, title: "saml saml saml is the best2")
open_post = Fabricate(:post, topic: open_topic, raw: "this topic is a story about saml")
result = Search.execute("story")
expect(result.posts.pluck(:id)).to eq([closed_post.id, open_post.id])
end
end
context "when max_duplicate_search_index_terms limits duplication" do
before { SearchIndexer.enable }