Browse Source

Fixes #4456 - Search without filters in KB should always get sorted by relevance instead of updated_at.

Rolf Schmidt 2 years ago
parent
commit
f2488bc5de

+ 1 - 1
app/models/ticket/selector/search_index.rb

@@ -26,7 +26,7 @@ class Ticket::Selector::SearchIndex < Ticket::Selector::Base
   end
 
   def query_sort_by_index(query)
-    query[:sort] = SearchIndexBackend.search_by_index_sort(options[:sort_by], options[:order_by])
+    query[:sort] = SearchIndexBackend.search_by_index_sort(sort_by: options[:sort_by], order_by: options[:order_by])
     query
   end
 

+ 5 - 3
lib/search_index_backend.rb

@@ -375,7 +375,7 @@ remove whole data from index
     end
   end
 
-  def self.search_by_index_sort(sort_by = nil, order_by = nil)
+  def self.search_by_index_sort(sort_by: nil, order_by: nil, fulltext: false)
     result = (sort_by || [])
       .map(&:to_s)
       .each_with_object([])
@@ -395,7 +395,8 @@ remove whole data from index
         )
       end
 
-    if result.blank?
+    # if we have no fulltext search then the primary default sort is updated at else score
+    if result.blank? && !fulltext
       result.push(
         updated_at: {
           order: 'desc',
@@ -636,6 +637,7 @@ generate url for index or document access (only for internal use)
 @option options [Hash] :query_extension applied to ElasticSearch query
 @option options [Array<String>] :order_by ordering directions, desc or asc
 @option options [Array<String>] :sort_by fields to sort by
+@option options [Array<String>] :fulltext If no sorting is defined the current fallback is the sorting by updated_at. But for fulltext searches it makes more sense to search by _score as default. This parameter allows to change to the fallback to _score.
 
 =end
 
@@ -650,7 +652,7 @@ generate url for index or document access (only for internal use)
     data = {
       from:  options[:from],
       size:  options[:limit],
-      sort:  search_by_index_sort(options[:sort_by], options[:order_by]),
+      sort:  search_by_index_sort(sort_by: options[:sort_by], order_by: options[:order_by], fulltext: options[:fulltext]),
       query: {
         bool: {
           must: []

+ 5 - 0
lib/search_knowledge_base_backend.rb

@@ -215,6 +215,10 @@ class SearchKnowledgeBaseBackend
     hash[:order_by] = @params[:order_by].values
   end
 
+  def options_apply_fulltext(hash)
+    hash[:fulltext] = true
+  end
+
   def options(pagination: nil)
     output = base_options
 
@@ -222,6 +226,7 @@ class SearchKnowledgeBaseBackend
     options_apply_scope(output)
     options_apply_pagination(output, pagination)
     options_apply_order(output)
+    options_apply_fulltext(output)
 
     output
   end

+ 18 - 0
spec/lib/search_index_backend_spec.rb

@@ -847,4 +847,22 @@ RSpec.describe SearchIndexBackend do
       end
     end
   end
+
+  describe '.search_by_index_sort' do
+    it 'does return a sort value' do
+      expect(described_class.search_by_index_sort(sort_by: ['title'], order_by: 'desc')).to eq([{ 'title.keyword'=>{ order: 'd' } }, '_score'])
+    end
+
+    it 'does return a sort value for fulltext searches' do
+      expect(described_class.search_by_index_sort(sort_by: ['title'], order_by: 'desc', fulltext: true)).to eq([{ 'title.keyword'=>{ order: 'd' } }, '_score'])
+    end
+
+    it 'does return a default sort value' do
+      expect(described_class.search_by_index_sort).to eq([{ updated_at: { order: 'desc' } }, '_score'])
+    end
+
+    it 'does return a default sort value for fulltext searches' do
+      expect(described_class.search_by_index_sort(fulltext: true)).to eq(['_score'])
+    end
+  end
 end