如何基于模型实例language字段配置PgSearch多搜索词干字典语言
解决PgSearch多搜索按实例动态设置词干字典的问题
方案一:改用pg_search_scope替代multisearch
multisearch的全局配置确实无法直接按实例动态指定字典,换用pg_search_scope可以在查询时根据记录的language字段灵活选择对应字典:
class MyModel < ApplicationRecord include PgSearch::Model # 定义支持动态传参的搜索scope pg_search_scope :search_by_language, against: %i[my_column my_other_column], using: { tsearch: { ignoring: :accents, # 用lambda接收查询时传入的字典参数 dictionary: ->(language) { language.presence || 'english' } } } end
使用示例:
# 搜索语言为french的匹配记录 MyModel.where(language: 'french').search_by_language('bonjour', language: 'french') # 无指定语言时默认用english MyModel.search_by_language('hello')
方案二:扩展multisearch索引表,自定义生成逻辑
如果必须保留multisearch功能,可以通过扩展索引表、覆盖索引生成方法实现动态字典:
- 给
pg_search_documents表添加language字段:
# 生成迁移文件 rails generate migration AddLanguageToPgSearchDocuments language:string # 执行迁移 rails db:migrate
- 修改模型,覆盖默认的索引生成逻辑:
class MyModel < ApplicationRecord include PgSearch::Model multisearchable against: %i[my_column my_other_column] # 重写索引文档生成方法,动态使用实例的language作为字典 def pg_search_document document = super document.language = self.language # 手动生成对应语言的全文索引内容 document.content = PgSearch::Multisearch.rebuild_content( self, using: { tsearch: { dictionary: self.language.presence || 'english', ignoring: :accents } } ) document end end
- 重建所有索引:
MyModel.rebuild_pg_search_documents
- 查询时结合语言筛选:
PgSearch::Document.where(language: 'german').search('schlüssel').map(&:searchable)
注意:需要确保PostgreSQL已安装对应语言的词干字典,比如安装德语字典:
CREATE EXTENSION dict_de;
内容的提问来源于stack exchange,提问作者Pierre
相关产品推荐
相关产品推荐

