about summary refs log tree commit diff
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-12-15 18:41:40 +0100
committerGitHub <noreply@github.com>2022-12-15 18:41:40 +0100
commitbf1c7e2122dee94a5ace33a4a70aba7ba8de3bc0 (patch)
tree1ef656f85444fcd57bb48ba1b30030b61f8b550f
parent7fbc17afa246c5cd384123ace51e07622204b67c (diff)
Ensure exact match is the first result in hashtag searches (#21315)
Fixes #17494
-rw-r--r--app/services/tag_search_service.rb18
1 files changed, 17 insertions, 1 deletions
diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb
index b78d65625..b66ccced9 100644
--- a/app/services/tag_search_service.rb
+++ b/app/services/tag_search_service.rb
@@ -76,11 +76,27 @@ class TagSearchService < BaseService
     definition = TagsIndex.query(query)
     definition = definition.filter(filter) if @options[:exclude_unreviewed]
 
-    definition.limit(@limit).offset(@offset).objects.compact
+    ensure_exact_match(definition.limit(@limit).offset(@offset).objects.compact)
   rescue Faraday::ConnectionFailed, Parslet::ParseFailed
     nil
   end
 
+  # Since the ElasticSearch Query doesn't guarantee the exact match will be the
+  # first result or that it will even be returned, patch the results accordingly
+  def ensure_exact_match(results)
+    return results unless @offset.nil? || @offset.zero?
+
+    normalized_query = Tag.normalize(@query)
+    exact_match = results.find { |tag| tag.name.downcase == normalized_query }
+    exact_match ||= Tag.find_normalized(normalized_query)
+    unless exact_match.nil?
+      results.delete(exact_match)
+      results = [exact_match] + results
+    end
+
+    results
+  end
+
   def from_database
     Tag.search_for(@query, @limit, @offset, @options)
   end