|
@@ -9,7 +9,9 @@ class SearchKnowledgeBaseBackend
|
|
# @option params [KnowledgeBase::Category] :scope (nil) optional search scope
|
|
# @option params [KnowledgeBase::Category] :scope (nil) optional search scope
|
|
# @option params [Symbol] :flavor (:public) agent or public to indicate source and narrow down to internal or public answers accordingly
|
|
# @option params [Symbol] :flavor (:public) agent or public to indicate source and narrow down to internal or public answers accordingly
|
|
# @option params [String, Array<String>] :index (nil) indexes to limit search to, searches all indexes if nil
|
|
# @option params [String, Array<String>] :index (nil) indexes to limit search to, searches all indexes if nil
|
|
|
|
+ # @option params [Integer] :limit per page param for paginatin
|
|
# @option params [Boolean] :highlight_enabled (true) highlight matching text
|
|
# @option params [Boolean] :highlight_enabled (true) highlight matching text
|
|
|
|
+ # @option params [Hash<String=>String>, Hash<Symbol=>Symbol>] :order_by hash with column => asc/desc
|
|
|
|
|
|
def initialize(params)
|
|
def initialize(params)
|
|
@params = params.compact
|
|
@params = params.compact
|
|
@@ -17,23 +19,18 @@ class SearchKnowledgeBaseBackend
|
|
prepare_scope_ids
|
|
prepare_scope_ids
|
|
end
|
|
end
|
|
|
|
|
|
- def search(query, user: nil)
|
|
|
|
- raw_results = if SearchIndexBackend.enabled?
|
|
|
|
- SearchIndexBackend
|
|
|
|
- .search(query, indexes, options)
|
|
|
|
- .map do |hash|
|
|
|
|
- hash[:id] = hash[:id].to_i
|
|
|
|
- hash
|
|
|
|
- end
|
|
|
|
- else
|
|
|
|
- search_fallback(query, indexes, { user: user })
|
|
|
|
- end
|
|
|
|
-
|
|
|
|
- if (limit = @params.fetch(:limit, nil))
|
|
|
|
- raw_results = raw_results[0, limit]
|
|
|
|
|
|
+ def search(query, user: nil, pagination: nil)
|
|
|
|
+ raw_results = raw_results(query, user, pagination: pagination)
|
|
|
|
+
|
|
|
|
+ filtered = filter_results raw_results, user
|
|
|
|
+
|
|
|
|
+ if pagination
|
|
|
|
+ filtered = filtered.slice pagination.offset, pagination.limit
|
|
|
|
+ elsif @params[:limit]
|
|
|
|
+ filtered = filtered.slice 0, @params[:limit]
|
|
end
|
|
end
|
|
|
|
|
|
- filter_results raw_results, user
|
|
|
|
|
|
+ filtered
|
|
end
|
|
end
|
|
|
|
|
|
def search_fallback(query, indexes, options)
|
|
def search_fallback(query, indexes, options)
|
|
@@ -47,10 +44,26 @@ class SearchKnowledgeBaseBackend
|
|
.constantize
|
|
.constantize
|
|
.search_fallback("%#{query}%", @cached_scope_ids, options: options)
|
|
.search_fallback("%#{query}%", @cached_scope_ids, options: options)
|
|
.where(kb_locale: kb_locales)
|
|
.where(kb_locale: kb_locales)
|
|
|
|
+ .order(**search_fallback_order)
|
|
.pluck(:id)
|
|
.pluck(:id)
|
|
.map { |id| { id: id, type: index } }
|
|
.map { |id| { id: id, type: index } }
|
|
end
|
|
end
|
|
|
|
|
|
|
|
+ def search_fallback_order
|
|
|
|
+ @params[:order_by].presence || { updated_at: :desc }
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def raw_results(query, user, pagination: nil)
|
|
|
|
+ return search_fallback(query, indexes, { user: user }) if !SearchIndexBackend.enabled?
|
|
|
|
+
|
|
|
|
+ SearchIndexBackend
|
|
|
|
+ .search(query, indexes, options(pagination: pagination))
|
|
|
|
+ .map do |hash|
|
|
|
|
+ hash[:id] = hash[:id].to_i
|
|
|
|
+ hash
|
|
|
|
+ end
|
|
|
|
+ end
|
|
|
|
+
|
|
def filter_results(raw_results, user)
|
|
def filter_results(raw_results, user)
|
|
raw_results
|
|
raw_results
|
|
.group_by { |result| result[:type] }
|
|
.group_by { |result| result[:type] }
|
|
@@ -162,28 +175,56 @@ class SearchKnowledgeBaseBackend
|
|
@params.fetch(:flavor, :public).to_sym
|
|
@params.fetch(:flavor, :public).to_sym
|
|
end
|
|
end
|
|
|
|
|
|
- def options
|
|
|
|
- output = {
|
|
|
|
|
|
+ def base_options
|
|
|
|
+ {
|
|
query_extension: {
|
|
query_extension: {
|
|
bool: {
|
|
bool: {
|
|
must: [ { terms: { kb_locale_id: kb_locale_ids } } ]
|
|
must: [ { terms: { kb_locale_id: kb_locale_ids } } ]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ end
|
|
|
|
|
|
- if @params.fetch(:highlight_enabled, true)
|
|
|
|
- output[:highlight_fields_by_indexes] = {
|
|
|
|
- 'KnowledgeBase::Answer::Translation': %w[title content.body attachment.content tags],
|
|
|
|
- 'KnowledgeBase::Category::Translation': %w[title],
|
|
|
|
- 'KnowledgeBase::Translation': %w[title]
|
|
|
|
- }
|
|
|
|
- end
|
|
|
|
|
|
+ def options_apply_highlight(hash)
|
|
|
|
+ return if !@params.fetch(:highlight_enabled, true)
|
|
|
|
|
|
- if @params.fetch(:scope, nil)
|
|
|
|
- scope = { terms: { scope_id: @cached_scope_ids } }
|
|
|
|
|
|
+ hash[:highlight_fields_by_indexes] = {
|
|
|
|
+ 'KnowledgeBase::Answer::Translation': %w[title content.body attachment.content tags],
|
|
|
|
+ 'KnowledgeBase::Category::Translation': %w[title],
|
|
|
|
+ 'KnowledgeBase::Translation': %w[title]
|
|
|
|
+ }
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def options_apply_scope(hash)
|
|
|
|
+ return if !@params.fetch(:scope, nil)
|
|
|
|
|
|
- output[:query_extension][:bool][:must].push scope
|
|
|
|
|
|
+ hash[:query_extension][:bool][:must].push({ terms: { scope_id: @cached_scope_ids } })
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def options_apply_pagination(hash, pagination)
|
|
|
|
+ if @params[:from] && @params[:limit]
|
|
|
|
+ hash[:from] = @params[:from]
|
|
|
|
+ hash[:limit] = @params[:limit]
|
|
|
|
+ elsif pagination
|
|
|
|
+ hash[:from] = 0
|
|
|
|
+ hash[:limit] = pagination.limit * 99
|
|
end
|
|
end
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def options_apply_order(hash)
|
|
|
|
+ return if @params[:order_by].blank?
|
|
|
|
+
|
|
|
|
+ hash[:sort_by] = @params[:order_by].keys
|
|
|
|
+ hash[:order_by] = @params[:order_by].values
|
|
|
|
+ end
|
|
|
|
+
|
|
|
|
+ def options(pagination: nil)
|
|
|
|
+ output = base_options
|
|
|
|
+
|
|
|
|
+ options_apply_highlight(output)
|
|
|
|
+ options_apply_scope(output)
|
|
|
|
+ options_apply_pagination(output, pagination)
|
|
|
|
+ options_apply_order(output)
|
|
|
|
|
|
output
|
|
output
|
|
end
|
|
end
|