mirror of
https://github.com/meineerde/redmine.git
synced 2026-02-11 13:15:20 +00:00
Cache search result ids for faster search pagination (#18631).
git-svn-id: http://svn.redmine.org/redmine/trunk@13770 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
71172e2411
commit
717f491f50
@ -18,8 +18,6 @@
|
||||
class SearchController < ApplicationController
|
||||
before_filter :find_optional_project
|
||||
|
||||
@@search_cache_store ||= ActiveSupport::Cache.lookup_store :memory_store
|
||||
|
||||
def index
|
||||
@question = params[:q] || ""
|
||||
@question.strip!
|
||||
@ -57,7 +55,7 @@ class SearchController < ApplicationController
|
||||
|
||||
fetcher = Redmine::Search::Fetcher.new(
|
||||
@question, User.current, @scope, projects_to_search,
|
||||
:all_words => @all_words, :titles_only => @titles_only
|
||||
:all_words => @all_words, :titles_only => @titles_only, :cache => params[:page].present?
|
||||
)
|
||||
|
||||
if fetcher.tokens.present?
|
||||
|
||||
@ -47,6 +47,14 @@ module RedmineApp
|
||||
# Do not include all helpers
|
||||
config.action_controller.include_all_helpers = false
|
||||
|
||||
# Specific cache for search results, the default file store cache is not
|
||||
# a good option as it could grow fast. A memory store (32MB max) is used
|
||||
# as the default. If you're running multiple server processes, it's
|
||||
# recommended to switch to a shared cache store (eg. mem_cache_store).
|
||||
# See http://guides.rubyonrails.org/caching_with_rails.html#cache-stores
|
||||
# for more options (same options as config.cache_store).
|
||||
config.redmine_search_cache_store = :memory_store
|
||||
|
||||
config.session_store :cookie_store, :key => '_redmine_session'
|
||||
|
||||
if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
|
||||
|
||||
@ -31,6 +31,18 @@ module Redmine
|
||||
search_type = search_type.to_s
|
||||
@@available_search_types << search_type unless @@available_search_types.include?(search_type)
|
||||
end
|
||||
|
||||
# Returns the cache store for search results
|
||||
# Can be configured with config.redmine_search_cache_store= in config/application.rb
|
||||
def cache_store
|
||||
@@cache_store ||= begin
|
||||
# if config.search_cache_store was not previously set, a no method error would be raised
|
||||
config = Rails.application.config.redmine_search_cache_store rescue :memory_store
|
||||
if config
|
||||
ActiveSupport::Cache.lookup_store config
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Fetcher
|
||||
@ -41,6 +53,7 @@ module Redmine
|
||||
@question = question.strip
|
||||
@scope = scope
|
||||
@projects = projects
|
||||
@cache = options.delete(:cache)
|
||||
@options = options
|
||||
|
||||
# extract tokens from the question
|
||||
@ -52,10 +65,12 @@ module Redmine
|
||||
@tokens.slice! 5..-1
|
||||
end
|
||||
|
||||
# Returns the total result count
|
||||
def result_count
|
||||
result_ids.size
|
||||
end
|
||||
|
||||
# Returns the result count by type
|
||||
def result_count_by_type
|
||||
ret = Hash.new {|h,k| h[k] = 0}
|
||||
result_ids.group_by(&:first).each do |scope, ids|
|
||||
@ -64,6 +79,7 @@ module Redmine
|
||||
ret
|
||||
end
|
||||
|
||||
# Returns the results for the given offset and limit
|
||||
def results(offset, limit)
|
||||
result_ids_to_load = result_ids[offset, limit] || []
|
||||
|
||||
@ -78,12 +94,31 @@ module Redmine
|
||||
end.compact
|
||||
end
|
||||
|
||||
# Returns the results ids, sorted by rank
|
||||
def result_ids
|
||||
@ranks_and_ids ||= load_result_ids
|
||||
@ranks_and_ids ||= load_result_ids_from_cache
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project_ids
|
||||
Array.wrap(@projects).map(&:id)
|
||||
end
|
||||
|
||||
def load_result_ids_from_cache
|
||||
if Redmine::Search.cache_store
|
||||
cache_key = ActiveSupport::Cache.expand_cache_key(
|
||||
[@question, @user.id, @scope.sort, @options, project_ids.sort]
|
||||
)
|
||||
|
||||
Redmine::Search.cache_store.fetch(cache_key, :force => !@cache) do
|
||||
load_result_ids
|
||||
end
|
||||
else
|
||||
load_result_ids
|
||||
end
|
||||
end
|
||||
|
||||
def load_result_ids
|
||||
ret = []
|
||||
# get all the results ranks and ids
|
||||
@ -95,6 +130,7 @@ module Redmine
|
||||
end
|
||||
# sort results, higher rank and id first
|
||||
ret.sort! {|a,b| b.last <=> a.last}
|
||||
# only keep ids now that results are sorted
|
||||
ret.map! {|scope, r| [scope, r.last]}
|
||||
ret
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user