2022-01-01 13:38:12 +00:00
|
|
|
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
|
2013-06-12 15:59:58 +00:00
|
|
|
|
2013-05-21 22:30:09 +00:00
|
|
|
class SearchController < ApplicationController
|
2017-02-15 12:29:25 +00:00
|
|
|
prepend_before_action :authentication_check
|
2013-05-21 22:30:09 +00:00
|
|
|
|
2015-08-15 23:27:11 +00:00
|
|
|
# GET|POST /api/v1/search
|
2015-08-05 09:47:00 +00:00
|
|
|
# GET|POST /api/v1/search/:objects
|
|
|
|
|
|
|
|
def search_generic
|
2014-09-19 21:35:40 +00:00
|
|
|
# get params
|
|
|
|
query = params[:query]
|
2017-11-23 08:09:44 +00:00
|
|
|
if query.respond_to?(:permit!)
|
|
|
|
query = query.permit!.to_h
|
|
|
|
end
|
2014-09-19 21:35:40 +00:00
|
|
|
limit = params[:limit] || 10
|
|
|
|
|
2015-08-05 09:47:00 +00:00
|
|
|
# convert objects string into array of class names
|
|
|
|
# e.g. user-ticket-another_object = %w( User Ticket AnotherObject )
|
2020-11-05 16:31:00 +00:00
|
|
|
objects = if params[:objects]
|
2016-01-15 17:22:57 +00:00
|
|
|
params[:objects].split('-').map(&:camelize)
|
2020-11-05 16:31:00 +00:00
|
|
|
else
|
|
|
|
Setting.get('models_searchable')
|
2016-01-15 17:22:57 +00:00
|
|
|
end
|
2015-08-16 00:53:27 +00:00
|
|
|
|
|
|
|
# get priorities of result
|
|
|
|
objects_in_order = []
|
|
|
|
objects_in_order_hash = {}
|
2017-10-01 12:25:52 +00:00
|
|
|
objects.each do |object|
|
2017-12-18 03:36:56 +00:00
|
|
|
local_class = object.constantize
|
|
|
|
preferences = local_class.search_preferences(current_user)
|
2015-08-16 00:53:27 +00:00
|
|
|
next if !preferences
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2017-12-18 03:36:56 +00:00
|
|
|
objects_in_order_hash[preferences[:prio]] = local_class
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
|
|
|
objects_in_order_hash.keys.sort.reverse_each do |prio|
|
2015-08-16 00:53:27 +00:00
|
|
|
objects_in_order.push objects_in_order_hash[prio]
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2015-08-16 00:53:27 +00:00
|
|
|
|
2019-03-26 00:17:17 +00:00
|
|
|
generic_search_params = {
|
|
|
|
query: query,
|
|
|
|
limit: limit,
|
|
|
|
current_user: current_user,
|
|
|
|
}
|
|
|
|
|
2014-09-19 21:35:40 +00:00
|
|
|
# try search index backend
|
|
|
|
assets = {}
|
|
|
|
result = []
|
|
|
|
if SearchIndexBackend.enabled?
|
2015-08-16 00:53:27 +00:00
|
|
|
|
|
|
|
# get direct search index based objects
|
|
|
|
objects_with_direct_search_index = []
|
|
|
|
objects_without_direct_search_index = []
|
2017-10-01 12:25:52 +00:00
|
|
|
objects.each do |object|
|
2015-08-16 00:53:27 +00:00
|
|
|
preferences = object.constantize.search_preferences(current_user)
|
|
|
|
next if !preferences
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-08-16 00:53:27 +00:00
|
|
|
if preferences[:direct_search_index]
|
|
|
|
objects_with_direct_search_index.push object
|
|
|
|
else
|
|
|
|
objects_without_direct_search_index.push object
|
|
|
|
end
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2015-08-05 11:58:53 +00:00
|
|
|
|
2015-08-16 00:53:27 +00:00
|
|
|
# do only one query to index search backend
|
2017-09-11 00:50:05 +00:00
|
|
|
if objects_with_direct_search_index.present?
|
2018-11-06 16:11:10 +00:00
|
|
|
items = SearchIndexBackend.search(query, objects_with_direct_search_index, limit: limit)
|
2017-10-01 12:25:52 +00:00
|
|
|
items.each do |item|
|
2019-01-06 18:41:29 +00:00
|
|
|
local_class = item[:type].constantize
|
2017-12-18 03:36:56 +00:00
|
|
|
record = local_class.lookup(id: item[:id])
|
2017-07-24 07:06:15 +00:00
|
|
|
next if !record
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-08-16 00:53:27 +00:00
|
|
|
assets = record.assets(assets)
|
2017-12-18 03:36:56 +00:00
|
|
|
item[:type] = local_class.to_app_model.to_s
|
2015-08-05 11:58:53 +00:00
|
|
|
result.push item
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2015-08-05 11:58:53 +00:00
|
|
|
end
|
2015-08-16 00:53:27 +00:00
|
|
|
|
|
|
|
# e. g. do ticket query by Ticket class to handle ticket permissions
|
2017-10-01 12:25:52 +00:00
|
|
|
objects_without_direct_search_index.each do |object|
|
2019-03-26 00:17:17 +00:00
|
|
|
object_result = search_generic_backend(object.constantize, assets, generic_search_params)
|
2017-09-11 00:50:05 +00:00
|
|
|
if object_result.present?
|
2020-09-30 09:07:01 +00:00
|
|
|
result.concat(object_result)
|
2015-08-16 00:53:27 +00:00
|
|
|
end
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2015-08-16 00:53:27 +00:00
|
|
|
|
|
|
|
# sort order by object priority
|
|
|
|
result_in_order = []
|
2017-10-01 12:25:52 +00:00
|
|
|
objects_in_order.each do |object|
|
|
|
|
result.each do |item|
|
2017-12-18 03:36:56 +00:00
|
|
|
next if item[:type] != object.to_app_model.to_s
|
2018-10-09 06:17:41 +00:00
|
|
|
|
2015-08-16 00:53:27 +00:00
|
|
|
item[:id] = item[:id].to_i
|
|
|
|
result_in_order.push item
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
|
|
|
end
|
2015-08-16 00:53:27 +00:00
|
|
|
result = result_in_order
|
|
|
|
|
2014-09-19 21:35:40 +00:00
|
|
|
else
|
2015-08-05 11:58:53 +00:00
|
|
|
|
2014-09-19 21:35:40 +00:00
|
|
|
# do query
|
2017-10-01 12:25:52 +00:00
|
|
|
objects_in_order.each do |object|
|
2019-03-26 00:17:17 +00:00
|
|
|
object_result = search_generic_backend(object, assets, generic_search_params)
|
2017-09-11 00:50:05 +00:00
|
|
|
if object_result.present?
|
2020-09-30 09:07:01 +00:00
|
|
|
result.concat(object_result)
|
2015-08-05 09:47:00 +00:00
|
|
|
end
|
2017-10-01 12:25:52 +00:00
|
|
|
end
|
2014-09-19 21:35:40 +00:00
|
|
|
end
|
|
|
|
|
2015-04-27 13:42:53 +00:00
|
|
|
render json: {
|
|
|
|
assets: assets,
|
|
|
|
result: result,
|
2014-09-19 21:35:40 +00:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2015-08-16 00:53:27 +00:00
|
|
|
private
|
|
|
|
|
2019-03-26 00:17:17 +00:00
|
|
|
=begin
|
|
|
|
|
|
|
|
search generic backend
|
|
|
|
|
|
|
|
SearchController#search_generic_backend(
|
|
|
|
Ticket, # object
|
|
|
|
{}, # assets
|
|
|
|
query: "search query",
|
|
|
|
limit: 10,
|
|
|
|
current_user: user,
|
|
|
|
)
|
|
|
|
|
|
|
|
=end
|
|
|
|
|
|
|
|
def search_generic_backend(object, assets, params)
|
|
|
|
found_objects = object.search(params)
|
2015-08-16 00:53:27 +00:00
|
|
|
result = []
|
|
|
|
found_objects.each do |found_object|
|
|
|
|
item = {
|
|
|
|
id: found_object.id,
|
2017-12-18 03:36:56 +00:00
|
|
|
type: found_object.class.to_app_model.to_s
|
2015-08-16 00:53:27 +00:00
|
|
|
}
|
|
|
|
result.push item
|
|
|
|
assets = found_object.assets(assets)
|
|
|
|
end
|
|
|
|
result
|
|
|
|
end
|
2013-05-21 22:30:09 +00:00
|
|
|
end
|