如何结合Searchkick与Globalize实现i18n翻译数据的重新索引?
解决Searchkick与Globalize结合的多语言数据重新索引问题
我之前也碰到过一模一样的场景——用Globalize做多语言翻译,搭配Searchkick做搜索时,默认的索引逻辑根本不会自动处理翻译字段的更新,折腾了好一阵才搞定,下面是一步步的解决方案:
1. 自定义Searchkick的索引数据
Searchkick默认只会索引主模型(Service)的原生属性,不会自动抓取Globalize生成的翻译字段。我们得在Service模型里重写search_data方法,把需要的翻译字段主动包含进去:
class Service < ApplicationRecord translates :description, :name searchkick def search_data # 基础属性 + 所有语言的翻译字段(适合跨语言搜索场景) attributes.merge( name_en: translations.where(locale: 'en').first&.name, name_zh: translations.where(locale: 'zh-CN').first&.name, description_en: translations.where(locale: 'en').first&.description, description_zh: translations.where(locale: 'zh-CN').first&.description # 根据你系统支持的语言继续添加对应的字段 ) # 如果你的系统只在单一语言环境下运行,也可以用这种动态索引当前locale的写法 # attributes.merge( # name: name, # description: description # ) end end
这里提供了两种思路,你可以根据业务场景选:
- 把所有语言的翻译字段作为独立字段索引(比如
name_en、name_zh):适合需要跨语言搜索,或者搜索时按语言筛选的场景。 - 只索引当前locale的翻译内容:适合系统固定单语言运行的场景,但切换locale后需要重新执行全量索引。
2. 触发翻译更新时的自动重新索引
当你修改ServiceTranslation的内容时,主模型Service不会自动触发Searchkick的重新索引,所以得在ServiceTranslation模型里加个回调:
class ServiceTranslation < ApplicationRecord belongs_to :service after_save :reindex_service after_destroy :reindex_service private def reindex_service service.reindex # 数据量大的话推荐用异步索引:service.reindex_async end end
如果你的系统数据量比较大,建议用reindex_async,不过要确保你的异步任务队列(比如Sidekiq)已经配置好能正常运行。
3. 手动触发全量重新索引
完成上面的配置后,你需要手动触发一次全量重新索引,让现有数据的翻译内容都被正确同步到搜索索引里:
在Ubuntu终端里打开Rails控制台:
rails c
然后执行全量索引命令:
Service.reindex # 异步全量索引可以用 Service.reindex_async
或者直接用rake命令(适配大部分Searchkick版本):
rake searchkick:reindex CLASS=Service
验证索引是否生效
你可以在控制台里快速测试,确认翻译内容是否被正确索引:
# 搜索英文名称 Service.search("your_en_service_name") # 搜索中文名称(如果索引了中文字段) Service.search("你的中文服务名称", fields: [:name_zh])
内容的提问来源于stack exchange,提问作者fidato
相关产品推荐
相关产品推荐

