From bf1c7e2122dee94a5ace33a4a70aba7ba8de3bc0 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 15 Dec 2022 18:41:40 +0100 Subject: [PATCH] Ensure exact match is the first result in hashtag searches (#21315) Fixes #17494 --- app/services/tag_search_service.rb | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb index b78d65625d..b66ccced9d 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