如何在Rails中用低级缓存缓存Searchkick结果并避免缓存失效?
解决Searchkick搜索结果缓存失效的问题
问题核心在于直接缓存Searchkick.search()返回的Searchkick::Results实例时,该对象包含每次搜索生成的唯一元数据(如search.id),即使搜索条件完全一致,这些唯一属性也会导致缓存无法正确命中。
解决方案:提取核心数据缓存
不要缓存整个Searchkick::Results对象,而是提取其中与搜索结果相关的核心数据(不包含唯一元数据)进行缓存,之后再从缓存中还原所需的信息。
具体实现代码:
# 构建缓存key(保持原逻辑即可) cache_key = ["results_controller", @store, @category, @search, @page] # 缓存提取后的核心数据,而非整个Results对象 cached_search_data = Rails.cache.fetch(cache_key, expires_in: 1.week) do # 执行搜索 raw_results = Searchkick.search( @search, models: [YourFirstModel, YourSecondModel], # 替换为你的多模型 page: @page, # 其他搜索参数(如per_page、filters等) ) # 提取需要缓存的核心数据 { records: raw_results.results, # 匹配的记录数组 total_count: raw_results.total_count, # 总结果数 current_page: raw_results.current_page,# 当前页码 per_page: raw_results.per_page, # 每页条数 total_pages: raw_results.total_pages # 总页数 } end # 从缓存数据中赋值给控制器变量,按需使用 @items = cached_search_data[:records] @total_count = cached_search_data[:total_count] @pagination = { current_page: cached_search_data[:current_page], total_pages: cached_search_data[:total_pages], per_page: cached_search_data[:per_page] }
关键说明:
raw_results.results返回的是匹配的ActiveRecord对象数组,不包含Searchkick的唯一元数据,相同搜索条件下内容完全一致,适合缓存。- 分页统计信息(total_count、current_page等)是数值或整数,不会随每次请求变化,可安全缓存。
- 若关联模型(如
@store、@category)更新,其自带的cache_key会自动变化,导致缓存key更新,从而自动刷新缓存,保证数据一致性。
内容的提问来源于stack exchange,提问作者sambehera
相关产品推荐
相关产品推荐

